I have an initialState like the following:
import { createSlice } from '@reduxjs/toolkit';
const initialBannerContentState = [
{
id: '1',
name: 'bg',
url: '',
isSet: false,
x: 0,
y: 0
},
{
id: '2',
name: 'logo',
url: '',
isSet: false,
x: 0,
y: 0
}
];
const bannerContentSlice = createSlice({
name: 'bannerContent',
initialState: initialBannerContentState,
reducers: {
updateBannerContent(state, action) {
const { id, item, value } = action.payload;
const existing = state.find((item) => item.id === id);
if (existing) {
switch (item) {
case 'url':
existing.url = value;
break;
.... // and more
default:
}
}
},
resetBannerContent(state, action) {
const { id, item } = action.payload;
const existing = state.find((item) => item.id === id);
if (existing) {
switch (item) {
case 'bg': // item with id 1
initialBannerContentState[id];
break;
.... // and more
default:
}
}
}
}
});
export const BannerContentActions = bannerContentSlice.actions;
export default bannerContentSlice.reducer;
Then I am using it like:
import { useDispatch } from 'react-redux';
import { BannerContentActions } from '../../store/bannerContent';
const someThing = () => {
const dispatch = useDispatch();
return (
<div>
<Button onClick={
dispatch(BannerContentActions.updateBannerContent({
id: '1',
item: 'bg',
url: 'someimageurl'
}));
dispatch(BannerContentActions.updateBannerContent({
id: '1',
item: 'isSet',
url: true
}));
}>
Setting some image url
</Button>
<Button onClick={
dispatch(BannerContentActions.resetBannerContent({
id: '1',
item: 'bg'
}));
}>
Resetting initial data id 1
</Button>
</div>
);
export default something;
So what I am trying to do is to reset everything for id 1 to its initial state. The update function does work, but the reset doesn't do anything. Nothing is changed on the id object.
So I am not sure where it goes wrong, most likely its some logic, but I can't figure it out.
It doesn't appear that the resetBannerContent
reducer case is mutating the state object or returning a new state object value.
I'd suggest searching for the index of the matching element object and mutate the state at that index with the initial state value of the same index.
You also should be dispatching the action within a callback function, not immediately when the button renders, e.g. onClick={() => dispatch(...)}
instead of onClick={dispatch(...)}
.
Example:
resetBannerContent(state, action) {
const { id, name } = action.payload;
const index = state.findIndex(
(item) => item.id === id && item.name === name
);
if (index !== -1) {
state[index] = initialBannerContentState[index];
}
}
<Button
onClick={() => {
dispatch(BannerContentActions.resetBannerContent({
id: '1',
name: 'bg'
}));
}}
>
Resetting initial data id 1
</Button>
Note: If the item.id
properties are globally unique you likely don't need to also pass the 'bg' name
value.
resetBannerContent(state, action) {
const index = state.findIndex((item) => item.id === action.payload);
if (index !== -1) {
state[index] = initialBannerContentState[index];
}
}
<Button onClick={() => dispatch(BannerContentActions.resetBannerContent('1'))}>
Resetting initial data id 1
</Button>