Skip to main content Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-react --skill redux-state-managementEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Ocupaciones relacionadasSOC
Basado en la clasificación ocupacional SOC
Explorador de archivos
4 archivos| name | redux-state-management |
| description | Master Redux Toolkit for production state management including slices, async thunks, RTK Query, and error handling |
| sasmp_version | 2.0.0 |
| bonded_agent | 04-state-management |
| bond_type | PRIMARY_BOND |
| input_validation | {"required_packages":[{"@reduxjs/toolkit":">=2.0.0"},{"react-redux":">=9.0.0"}]} |
| output_format | {"code_examples":"typescript","test_template":"jest"} |
| error_handling | {"patterns":["retry_query","optimistic_update","error_boundary"],"retry_config":{"max_retries":3,"backoff_multiplier":2}} |
| observability | {"logging":"redux_devtools","metrics":["action_count","state_size"]} |
Redux State Management Skill
Overview
Master Redux Toolkit for state management in React applications, including store configuration, slices, async operations, and RTK Query for API state.
Learning Objectives
- Configure Redux store with Redux Toolkit
- Create slices and reducers
- Handle async operations with createAsyncThunk
- Use RTK Query for API data management
- Integrate Redux DevTools
Quick Start
Installation
npm install @reduxjs/toolkit react-redux
Store Setup
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './features/counter/counterSlice';
import userReducer from './features/user/userSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
user: userReducer
}
});
import { Provider } from 'react-redux';
import { store } from './store';
function App() {
return (
<Provider store={store}>
<YourApp />
</Provider>
);
}
Creating Slices
{ createSlice } ;
counterSlice = ({
: ,
: { : },
: {
: {
state. += ;
},
: {
state. -= ;
},
: {
state. += action.;
}
}
});
{ increment, decrement, incrementByAmount } = counterSlice.;
counterSlice.;
import
from
'@reduxjs/toolkit'
const
createSlice
name
'counter'
initialState
value
0
reducers
increment
(state) =>
value
1
decrement
(state) =>
value
1
incrementByAmount
(state, action) =>
value
payload
export
const
actions
export
default
reducer
Using Redux in Components
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
}
Async Operations
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId) => {
const response = await fetch(`/api/users/${userId}`);
return response.json();
}
);
const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
status: 'idle',
error: null
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.status = 'succeeded';
state.user = action.payload;
})
.addCase(fetchUser.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
}
});
export default userSlice.reducer;
RTK Query
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
tagTypes: ['Posts', 'Users'],
endpoints: (builder) => ({
getPosts: builder.query({
query: () => '/posts',
providesTags: ['Posts']
}),
getPost: builder.query({
query: (id) => `/posts/${id}`,
providesTags: (result, error, id) => [{ type: 'Posts', id }]
}),
addPost: builder.mutation({
query: (post) => ({
url: '/posts',
method: 'POST',
body: post
}),
invalidatesTags: ['Posts']
}),
updatePost: builder.mutation({
query: ({ id, ...patch }) => ({
url: `/posts/${id}`,
method: 'PATCH',
body: patch
}),
invalidatesTags: (result, error, { id }) => [{ type: 'Posts', id }]
})
})
});
export const {
useGetPostsQuery,
useGetPostQuery,
useAddPostMutation,
useUpdatePostMutation
} = api;
Using RTK Query in Components
function PostList() {
const { data: posts, isLoading, error } = useGetPostsQuery();
const [addPost] = useAddPostMutation();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{posts.map(post => (
<PostCard key={post.id} post={post} />
))}
<button onClick={() => addPost({ title: 'New Post' })}>
Add Post
</button>
</div>
);
}
Practice Exercises
- Build a todo app with Redux Toolkit
- Implement user authentication flow
- Create shopping cart with Redux
- Build API integration with RTK Query
- Implement optimistic updates
- Create normalized state with Entity Adapter
Resources
Error Handling Patterns
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/api',
prepareHeaders: (headers, { getState }) => {
const token = (getState() as RootState).auth.token;
if (token) headers.set('authorization', `Bearer ${token}`);
return headers;
},
}),
endpoints: (builder) => ({
getData: builder.query({
query: (id) => `data/${id}`,
extraOptions: { maxRetries: 3 },
transformErrorResponse: (response) => ({
status: response.status,
message: response.data?.message || 'Unknown error',
}),
}),
}),
});
Unit Test Template
import { configureStore } from '@reduxjs/toolkit';
import { renderHook, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { api } from './api';
describe('Redux State', () => {
const wrapper = ({ children }) => (
<Provider store={configureStore({ reducer: { [api.reducerPath]: api.reducer } })}>
{children}
</Provider>
);
it('should fetch data successfully', async () => {
const { result } = renderHook(() => api.useGetDataQuery(1), { wrapper });
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(result.current.data).toBeDefined();
});
});
Version: 2.0.0
Last Updated: 2025-12-30
SASMP Version: 2.0.0
Difficulty: Intermediate
Estimated Time: 2-3 weeks
Prerequisites: React Hooks, State Management Concepts
Changelog: Added RTK Query patterns, error handling, and test templates