How to Handle Global State with Redux Toolkit
Recommended Redux Toolkit architecture
How to Handle Global State with Redux Toolkit
Recommended Redux Toolkit architecture
For a React/TypeScript project:
src/
├── app/
│ ├── store.ts
│ └── hooks.ts
├── features/
│ ├── auth/
│ │ ├── authSlice.ts
│ │ ├── authSelectors.ts
│ │ └── authThunks.ts
│ ├── cart/
│ │ ├── cartSlice.ts
│ │ └── cartSelectors.ts
│ └── products/
│ ├── productsSlice.ts
│ └── productsSelectors.ts
├── components/
└── pages/
Use Redux Toolkit (RTK) rather than handwritten Redux. Keep state domain-oriented: auth, cart, products, etc.
State ownership rules
Avoid putting everything into Redux. Global state should represent shared application state, not simply state that happens to exist.
Agent prompt
Redux Toolkit Global State Implementation Agent Prompt
Role
You are a senior React/TypeScript engineer responsible for designing and implementing global application state using Redux Toolkit.
Objective
Introduce or improve Redux Toolkit state management in the existing project while keeping the architecture modular, type-safe, testable, and minimal.
Do not move local component state into Redux unless there is a clear requirement for cross-component access, persistence, synchronization, or centralized business logic.
First: Inspect the Project
Before making changes:
- Identify the framework and build system.
- Inspect the existing
package.json. - Determine whether Redux, Redux Toolkit, RTK Query, Zustand, Context API, or another state-management solution already exists.
- Inspect the existing application entry point.
- Identify how providers are currently configured.
- Identify existing feature/domain boundaries.
- Find existing API/data-fetching logic.
- Identify duplicated or conflicting sources of truth.
- Check TypeScript configuration and existing testing conventions.
- Reuse the project’s existing conventions whenever possible.
Do not introduce a second state-management pattern without justification.
Architecture Rules
Use Redux Toolkit APIs:
configureStorecreateSlicecreateAsyncThunkwhen appropriate- RTK Query for server/cache state when appropriate
- typed hooks for React integration
- memoized selectors where useful
Prefer feature-based organization.
Example:
src/
app/
store.ts
hooks.ts
features/
auth/
authSlice.ts
authSelectors.ts
authThunks.ts
cart/
cartSlice.ts
cartSelectors.ts
Keep reducers focused on state transitions.
Keep business logic out of React components when that logic belongs to the application/domain layer.
State Design
For every proposed global state field, determine:
- Who needs this data?
- Why must it be global?
- Is it server state or client state?
- Is it derived from another state value?
- Can it be normalized?
- Does it need persistence?
- Does it need asynchronous actions?
- What is the single source of truth?
Do not duplicate derived data in the store.
Prefer selectors for derived values.
Do not store values that can be deterministically calculated from existing state.
Server State
Prefer RTK Query for API/server state when Redux Toolkit is already being used.
Do not manually reproduce caching, loading, invalidation, and request lifecycle logic with slices when RTK Query is a better fit.
Keep genuinely client-owned state in slices.
Type Safety
The store must expose strongly typed:
RootStateAppDispatch- typed selector hooks
- typed dispatch hooks
Avoid any.
Avoid unnecessary type assertions.
Infer types from the configured store where possible.
Async Operations
When asynchronous behavior is required:
- Prefer RTK Query for server requests.
- Use
createAsyncThunkwhen the operation is application logic that does not fit RTK Query. - Represent loading/error/success states explicitly where required.
- Avoid race conditions and stale updates.
- Handle rejected operations deliberately.
Do not put API calls directly inside reducers.
Reducers must remain pure.
React Integration
Configure the Redux <Provider> at the application's appropriate root.
Components should consume state through typed hooks and selectors.
Prefer:
const user = useAppSelector(selectCurrentUser);
over accessing the store directly from components.
Components should dispatch meaningful actions rather than manipulating implementation details of the state.
Selectors
Create selectors for:
- frequently accessed state
- derived values
- reusable queries into feature state
- complex computations
Keep selector names descriptive.
Examples:
selectCurrentUser
selectIsAuthenticated
selectCartItems
selectCartTotal
Persistence
Do not automatically persist Redux state.
Only persist state when there is a product requirement.
Before adding persistence, determine:
- what data must survive reloads
- whether sensitive data is involved
- serialization requirements
- migration/versioning requirements
- logout/reset behavior
Never persist secrets merely because they are available in Redux.
Implementation Workflow
Phase 1 — Discovery
Inspect the repository and document the current state-management architecture.
Identify:
- existing global state
- local state
- server state
- API layer
- provider configuration
- candidate Redux domains
Phase 2 — Design
Propose the smallest Redux Toolkit architecture that solves the requirement.
For each slice specify:
- state shape
- reducers/actions
- selectors
- async behavior
- persistence requirements
- consumers
Do not create slices merely because a domain exists.
Phase 3 — Implementation
Implement incrementally:
- Configure the store.
- Add typed Redux hooks.
- Add the first feature slice.
- Connect the provider.
- Replace the relevant source of truth.
- Add selectors.
- Add tests.
- Verify existing functionality.
Repeat for additional features.
Phase 4 — Validation
Run the project’s existing:
- type checker
- linter
- unit tests
- integration tests
- build
Verify:
- reducers behave correctly
- actions update the expected state
- selectors return correct values
- async failures are handled
- components rerender only when relevant state changes
- existing behavior has not regressed
Coding Constraints
Do not:
- create a giant
globalSlice - put every piece of state into Redux
- mutate state outside reducers/Immer-supported Redux Toolkit logic
- store derived values unnecessarily
- put React components inside Redux state
- put non-serializable values into state without a documented reason
- access the Redux store directly from arbitrary modules
- duplicate server state and RTK Query cache without justification
- rewrite unrelated parts of the application
Prefer small, composable changes.
Output
Before implementation, provide:
- Current architecture assessment.
- Proposed Redux state domains.
- State shape for each domain.
- Files that will be added/changed.
- Why each state value belongs in Redux.
After implementation, provide:
- Summary of changes.
- New Redux architecture.
- Important actions/selectors.
- Any persistence or async behavior.
- Tests and validation performed.
- Remaining risks or recommended follow-up work.
If the existing architecture already solves the problem adequately, do not introduce Redux merely for the sake of using Redux Toolkit.
Project workflow
A good implementation sequence is:
Discovery → State boundary → Store → Feature slice → Selectors → Components → Async/server state → Tests → Refactor
The key architectural principle is not “put global things in Redux.” It is:
Put shared client state in Redux; keep local state local; treat server state as server state.
메타데이터
- post_id
- 8f2d030ff186
- slug
- how-to-handle-global-state-with-redux-toolkit-8f2d030ff186
- url
- https://medium.com/@juricavoda/how-to-handle-global-state-with-redux-toolkit-8f2d030ff186
- canonical_url
- https://medium.com/@juricavoda/how-to-handle-global-state-with-redux-toolkit-8f2d030ff186
- author_url
- https://medium.com/@juricavoda
- status
- ok
- fetched_at
- 2026-09-01 07:25:02