React Redux入门疑问:是否需为每个Action创建Reducer?Post场景求助
Hey there! Let's break this down clearly—this is such a common confusion when you're just starting out with React and Redux, so you're definitely not alone.
First, Let's Clarify Core Roles
Let's start with the basics to get aligned:
- Actions: These are plain objects that describe what happened (e.g., "I started a POST request", "The POST request succeeded"). When working with async logic (like Axios calls), you'll typically use a middleware like Redux Thunk to let your "Action" be a function instead of just an object—this lets you run async code before dispatching actual actions.
- Reducers: These are pure functions that take the current state and an action, then return a new state. They're the only way to update your Redux store's state.
Your Specific Scenario: POST Requests & Reducers
So you've created an Action that uses Axios to send a POST request, and you're dispatching it. Do you need a Reducer? Almost certainly yes—here's why:
When you make an async request, you almost always need to track the state of that request in your app:
- Is the request still loading? (Show a spinner in your UI)
- Did it succeed? (Show a success message, or update your data)
- Did it fail? (Show an error alert to the user)
All of these states (loading, success, error) live in your Redux store, and only a Reducer can update that store in response to Actions.
Let's Walk Through a Typical Flow
Here's how this would look in practice (using Redux Thunk for async support):
Create async action (thunk)
// actions/dataActions.js import axios from 'axios'; export const postData = (formData) => async (dispatch) => { // First, dispatch an action to signal the request started dispatch({ type: 'POST_DATA_REQUEST' }); try { // Run your Axios POST request const response = await axios.post('/api/your-endpoint', formData); // If successful, dispatch a success action with the response data dispatch({ type: 'POST_DATA_SUCCESS', payload: response.data }); } catch (err) { // If it fails, dispatch a failure action with the error dispatch({ type: 'POST_DATA_FAILURE', payload: err.message }); } };Create a Reducer to handle these actions
This is where you update the store state based on the actions dispatched:// reducers/dataReducer.js const initialState = { loading: false, error: null, savedData: null }; export const dataReducer = (state = initialState, action) => { switch (action.type) { case 'POST_DATA_REQUEST': return { ...state, loading: true, error: null }; case 'POST_DATA_SUCCESS': return { ...state, loading: false, savedData: action.payload }; case 'POST_DATA_FAILURE': return { ...state, loading: false, error: action.payload }; default: return state; } };Use the state in your component
Now you can connect your component to the store to access the loading/error/success state and update your UI accordingly:import { useSelector, useDispatch } from 'react-redux'; import { postData } from './actions/dataActions'; function MyForm() { const { loading, error, savedData } = useSelector(state => state.data); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); const formData = { /* your form data */ }; dispatch(postData(formData)); }; return ( <form onSubmit={handleSubmit}> {/* Your form fields */} {loading && <p>Saving...</p>} {error && <p className="error">Error: {error}</p>} {savedData && <p className="success">Data saved successfully!</p>} <button type="submit" disabled={loading}>Submit</button> </form> ); }
When Would You Not Need a Reducer?
The only time you might skip a Reducer is if you're making an async request where you don't care about the result at all—you just need to send data to the backend and don't need to update your UI or store state based on whether it worked. That's extremely rare though—most apps need to give users feedback about whether their action succeeded.
A Quick Note on Redux Toolkit
If you're just starting out, I highly recommend using Redux Toolkit (the official, recommended way to write Redux code). It simplifies this whole process with tools like createAsyncThunk (to handle async actions) and createSlice (to generate reducers and actions automatically), cutting down on boilerplate code.
内容的提问来源于stack exchange,提问作者shubhamr238

