xiaohongshu
xiaohongshu
asyncredux-base-action
Create a custom base action class for your app. Covers adding getter shortcuts to state parts, adding selector methods, implementing shared wrapError logic, and establishing project-wide action conventions.
Full skill instructions
Every AsyncRedux application should define an abstract base action class that all actions extend. This provides a central place for:
Create an abstract class extending ReduxAction<AppState>.
The recomended name is AppAction, in file app_action.dart:
abstract class AppAction extends ReduxAction<AppState> {
// All your actions will extend this class
}
Then extend AppAction instead of ReduxAction<AppState> in all your actions:
class IncrementCounter extends AppAction {
@override
AppState reduce() => state.copy(counter: state.counter + 1);
}
When your state has nested objects, add getters to simplify access:
abstract class AppAction extends ReduxAction<AppState> {
// Shortcuts to nested state parts
User get user => state.user;
Settings get settings => state.settings;
IList<Todo> get todos => state.todos;
Cart get cart => state.cart;
}
Now actions can write cleaner code:
class UpdateUserName extends AppAction {
final String name;
UpdateUserName(this.name);
@override
AppState reduce() {
// Instead of: state.user.name
// You can write: user.name
return state.copy(user: user.copy(name: name));
}
}
For common data lookups, add selector methods directly to your base action:
abstract class AppAction extends ReduxAction<AppState> {
// Getters for state parts
User get user => state.user;
IList<Item> get items => state.items;
// Selector methods
Item? findItemById(String id) =>
items.firstWhereOrNull((item) => item.id == id);
List<Item> get completedItems =>
items.where((item) => item.isCompleted).toList();
bool get isLoggedIn => user.isAuthenticated;
}
Actions can then use these selectors:
class MarkItemComplete extends AppAction {
final String itemId;
MarkItemComplete(this.itemId);
@override
AppState reduce() {
final item = findItemById(itemId);
if (item == null) return null; // No change
return state.copy(
items: items.replaceFirstWhere(
(i) => i.id == itemId,
item.copy(isCompleted: true),
),
);
}
}
For most applications, it's better to use instead a dedicated selector class to keep the base action clean:
class ActionSelect {
final AppState state;
ActionSelect(this.state);
Item? findById(String id) =>
state.items.firstWhereOrNull((item) => item.id == id);
List<Item> get completed =>
state.items.where((item) => item.isCompleted).toList();
List<Item> get pending =>
state.items.where((item) => !item.isCompleted).toList();
}
abstract class AppAction extends ReduxAction<AppState> {
ActionSelect get select => ActionSelect(state);
}
These namespaces selectors under select, enabling IDE autocompletion:
class ProcessItem extends AppAction {
final String itemId;
ProcessItem(this.itemId);
@override
AppState reduce() {
// IDE autocomplete shows: select.findById, select.completed, etc.
final item = select.findById(itemId);
// ...
}
}
For dependency injection, override the env getter in your base action:
class Environment {
final ApiClient api;
final AuthService auth;
final AnalyticsService analytics;
Environment({
required this.api,
required this.auth,
required this.analytics,
});
}
abstract class AppAction extends ReduxAction<AppState> {
// Type-safe access to environment
@override
Environment get env => super.env as Environment;
// Convenience getters for common services
ApiClient get api => env.api;
AuthService get auth => env.auth;
}
Actions can then use services directly:
class FetchUserProfile extends AppAction {
@override
Future<AppState?> reduce() async {
// Uses the api getter from base action
final profile = await api.getUserProfile();
return state.copy(user: profile);
}
}
URLs from the documentation:
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience