React新手求助:执行Reducer后Provider状态未更新
Hey there! Let's break down why your delete action isn't updating the UI even though the reducer is running. The main culprit is state mutation in your reducer, plus a small oversight in your App.js setup. Here's how to fix it:
1. Fix the Reducer's Immutability Violation
Redux relies on immutable state updates to detect changes. When you use splice on the original state array, you're modifying the existing state directly instead of returning a new array. Redux can't pick up this change because the array reference stays the same.
Replace your CommentsReducer.js with this version that returns a new array using filter:
import * as constants from '../Constants'; const CommentsReducer = (state=[ {id: '123', user: 'Test Reducer User', content: 'Test Content'}, {id: '456', user: 'Other Reducer User', content: 'Other Content'} ], action) => { switch(action.type) { case constants.REMOVE_COMMENT: // Return a NEW array excluding the target comment return state.filter(comment => comment.id !== action.comment.id); default: return state; } } export default CommentsReducer;
2. (Optional) Simplify the Delete Flow
Right now you're passing the entire comment object to your delete action. You can make this cleaner by only passing the comment ID:
Update Comment.js
Change the onClick handler to pass just the ID:
const Comment = ({ comment, onDeleteClick}) => ( <div className='comment'> <div className='comment-user'>{comment.user}</div> <div className='comment-content'>{comment.content}</div> <div className='delete-comment' onClick={() => onDeleteClick(comment.id)}>Delete</div> </div> )
Update CommentsAction.js
Modify the action to accept an ID instead of a comment object:
import * as constants from '../Constants'; export const removeComment = id => { return { type: constants.REMOVE_COMMENT, id } }
Update CommentsReducer.js (to match the simplified action)
case constants.REMOVE_COMMENT: return state.filter(comment => comment.id !== action.id);
3. Fix Initial Render in App.js
In your App.js, you defined a render function but never called it. Plus, with React-Redux's Provider, you don't need to manually set up a subscribe/render loop—Provider handles that automatically. Update your App.js to:
import React from 'react'; import CommentsContainer from './components/CommentsContainer'; import { createStore } from 'redux'; import commentsReducer from './reducers/CommentsReducer'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; const store = createStore(commentsReducer); const rootEl = document.getElementById('root'); ReactDOM.render( <Provider store={store}> <CommentsContainer /> </Provider>, rootEl );
Why This Works
- By returning a new array from the reducer, Redux detects the state change and triggers a re-render of your connected components.
- The
Providercomponent automatically subscribes to store changes, so you don't need to manually callrender()after each action. - Simplifying to pass only the ID makes your action and reducer more focused and efficient.
Give these changes a try, and your delete button should now update the UI correctly!
内容的提问来源于stack exchange,提问作者PlankTon

