I have a TOGGLE_SAVED
action in my reducer that I want to both toggle the saved
property on a target "image" object (within a loadedImages
array), as well as store that object in a savedImages
array in state.
I only want one image object in the current loadedImages
array to have saved
be true as I expect loadedImages
to repopulate upon some GET request, while keeping the saved image from the last request in savedImages
Right now my code looks as so:
const initialState = {
loadedImages: [],
savedImages: [],
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case LOAD_IMAGES:
return {
...state,
loadedImages: action.payload, // payload returns a fetch(...)[]
}
case TOGGLE_SAVED:
return {
...state,
loadedImages: state.loadedImages.map(img => {
if (img.id === action.payload.id) {
return {...img, saved: !img.saved}
} else {
return {...img, saved: false}
}
}),
savedImages: [
...state.loadedImages.filter(img => img.saved)
]
}
default:
return state
}
}
Right now, savedImages
is only populated when TOGGLE_SAVED
is ran twice and items within savedImages
do not persist over, every time loadedImages
is repopulated (via GET request).
Note: a typical "image" object is returned in payload as: {id: 0, saved: Boolean}
I believe in your current reducer, the savedImages
prop is actually using the previous reference to loadedImages
.
That's why it only works on the second run. You assume that the initial loadedImages
map()
runs and completes, and then moves on to the next prop, but that is not the case.
What could work is something like this:
case TOGGLE_SAVED:
const loadedImages = state.loadedImages.map(img => {
if (img.id === action.payload.id) {
return {...img, saved: !img.saved}
} else {
return {...img, saved: false}
})
return {
...state,
loadedImages,
savedImages: [
...loadedImages.filter(img => img.saved)
]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.