The Setup
I'm writing a reducer using createSlice
as such:
export const fetchUserProfile = createAsyncThunk(...)
export const UserProfileSlice = createSlice<UserProfileState | null, SliceCaseReducers<UserProfileState | null>>({
name: 'UserProfile',
initialState: null,
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchUserProfile.pending, (state, action) => {
console.log("Fetching user profile...")
})
builder.addCase(fetchUserProfile.rejected, (state, action) => {
// TODO: Handle this properly later.
console.log('Failed to fetch user profiles: ', action.payload)
})
builder.addCase(fetchUserProfile.fulfilled, (state, action) => {
console.log('State was: ', state)
state = action.payload
console.log('State is ', state)
})
}
})
export default UserProfileSlice.reducer
I'm adding the slice's reducer to my root reducer using combineReducers
, and I'm creating my store as such:
export const store = createStore(rootReducer, applyMiddleware(thunk));
I'm using the state in a component this way:
const user = useAppSelector(state => state.userProfileReducer)
Expected Behaviour
When the fetchUserProfile.fulfilled
action is dispatched, the state is updated and the component is re-rendered to reflect its data.
Actual Behaviour
The closure passed to the builder.addCase(fetchUserProfile.fulfilled,...)
is run (as evidenced by the console outputs), but its result is never reflected in the state as seen by the component.
I'm new to react native and the whole JS ecosystem, so I'm kinda stumped on debugging this. Thanks for your help.
CodePudding user response:
This is handled in Writing Immer Reducers: Mutating and Returning State.
state = newValue
does not have any effect. It does not modify the object in state
, but it throws away the object in state
and puts some new value into the variable.
Mutations of the object in state can be observed from outside of the function - simply changing the variable can not.
The solution?
Do return newValue
instead.