Reputation: 930
I have a slice called modal
which is responsible for showing and hiding a modal, using actions showModal
and hideModal
.
Here is what it looks like:
export const modal = createSlice({
slice: "modal",
initialState: {
visible: false,
selectedExpenseId: null
},
reducers:{
showModal: (state, { payload }) => (
state = {
visible: true,
selectedExpenseId: payload
}
),
hideModal: (state, {payload}) => (state = state.initialState)
//hideModal: (state, {payload}) => (state = {visible: false, selectedExpenseId: null})
}
});
showModal
works as intended, but when I call hideModal
nothing happens, as it seems I am unable to access initialState
in this manner.
When I resort to the commented out line which manually assigns the values in the intended way, it works.
I would like to know what I am doing wrong, as I would obviously prefer to be accessing initialState
properly. I am new to React and redux, so I'm sure that I'm probably just missing something obvious here.
Cheers.
Upvotes: 0
Views: 1492
Reputation: 67539
Both your reducers are currently wrong. You're seeing "correct" behavior for showModal
only by accident.
It looks like you're using Redux Starter Kit. Since that uses Immer inside, there are two ways you can update the state:
state
valueNeither of your reducers are actually doing that correctly.
Assigning state = something
inside of a reducer does not mutate the contents of state
, and it is not returning a new value. Instead, it's just changing what the local variable state
in this function is pointing to.
In addition, there is no state.initialState
field.
If showModal
is working, it's only by accident, possibly because the assignment statement is also implicitly returning the result of the assignment.
What you should be doing is something like this:
const initialState = {
visible: false,
selectedExpenseId: null
};
export const modal = createSlice({
slice: "modal",
initialState,
reducers: {
showModal(state, {payload}) {
return {visible: true, selectedExpenseId: payload};
},
hideModal(state) {
return initialState;
}
}
});
Note that you could also have written the reducers like:
showModal(state, {payload}) {
state.visible = true;
state.selectedExpenseId = payload;
}
(Source: I'm a Redux maintainer, and I wrote Redux Starter Kit.)
Upvotes: 1
Reputation: 104
Nowhere in the documentation of Redux is mentioned that you will receive a property in the state
named initialState
which will be containing the initial state.
Redux does not populate any property in the state
object by itself unless you do it in your reducers
or via initialState
.
There are various ways in which you can achieve the desired behaviour out of which you mentioned 1 in the question itself.
If you want to access it via initialState
, then you can follow the below logic:
const initialState = {
visible: false,
selectedExpenseId: null
};
export const modal = createSlice({
slice: "modal",
initialState: {...initialState},
reducers:{
showModal: (state, { payload }) => (
state = {
visible: true,
selectedExpenseId: payload
}
),
hideModal: (state, {payload}) => (state = {...initialState})
}
});
We have used spread notation (triple dot {...}) to avoid the mutation of the original initialState
object.
Upvotes: 0