更新ratings数组后状态中出现重复值问题
Hey there! Let's break down why your ratings array is showing duplicate entries in the state without needing a page refresh. Based on your description and the code snippet hint, here are the most likely issues and fixes to resolve this:
1. You're modifying the original array directly (Mutable Update)
The biggest culprit here is almost always mutating the existing ratings array instead of creating a new one. Redux relies on immutable state updates to detect changes properly. If you push the new rating directly to this.sitter.ratings, you're altering the original array reference—which can cause unexpected behavior like duplicate entries if the state isn't refreshed correctly.
❌ Bad (Mutable Code):
rateSitter(filledStars) { let rating = filledStars; let sitter: Sitter = this.sitter; // Directly mutates the original ratings array sitter.ratings.push(rating); dispatch(updateSitter(sitter)); }
✅ Good (Immutable Fix):
Create a new copy of the sitter object and its ratings array using the spread operator:
rateSitter(filledStars) { const rating = filledStars; // Create a new sitter object with a new ratings array const updatedSitter: Sitter = { ...this.sitter, ratings: [...this.sitter.ratings, rating] }; dispatch(updateSitter(updatedSitter)); }
2. Your Reducer isn't returning a new state object
Even if you dispatch an immutable update, if your reducer modifies the existing state instead of returning a new copy, Redux might not pick up the change correctly—and this can lead to duplicate entries if the state is reprocessed.
❌ Bad (Mutable Reducer):
case UPDATE_SITTER: // Modifies the existing sitter in state directly const existingSitter = state.sitters.find(s => s.id === action.payload.id); existingSitter.ratings = action.payload.ratings; return state;
✅ Good (Immutable Reducer):
Return a new state object with updated sitters and ratings:
case UPDATE_SITTER: return { ...state, sitters: state.sitters.map(sitter => sitter.id === action.payload.id ? { ...sitter, ratings: action.payload.ratings } : sitter ) };
3. Your Epic is dispatching duplicate actions
If you're using Redux-Observable, double-check your epic logic to make sure you aren't dispatching the UPDATE_SITTER action twice. This can happen if you do an optimistic local update and then re-dispatch the update when the API response comes back, without handling duplicates.
Example of a problematic Epic:
const rateSitterEpic = action$ => action$.pipe( ofType(RATE_SITTER), mergeMap(action => { // Optimistic update (local) dispatch(updateSitter({ ...action.payload.sitter, ratings: [...action.payload.sitter.ratings, action.payload.rating] })); // API call that also dispatches UPDATE_SITTER on success return api.post(`sitters/${action.payload.id}/rate`, { rating: action.payload.rating }) .pipe(map(res => updateSitter(res.data))); }) );
Fix for duplicate dispatch:
Either skip the optimistic update, or ensure the API response's updated sitter replaces the entire ratings array (instead of adding the rating again).
4. Optimistic update duplication
If you're using optimistic updates, make sure the API response doesn't send back the sitter with the new rating already added—then you don't need to add it again locally. If the API returns the full updated sitter, just use that object directly in your reducer to overwrite the existing one.
内容的提问来源于stack exchange,提问作者CodeHip

