如何在Redux中以可切换状态持久化数据

时间:2019-11-27 02:16:23

标签: javascript arrays redux state

我在化简器中有一个TOGGLE_SAVED动作,我想同时切换目标“图像”对象(在saved数组中)的loadedImages属性以及存储状态为savedImages数组中的对象。

我只希望当前loadedImages数组中的一个图像对象具有saved为真,因为我希望loadedImages根据某些GET请求重新填充,同时保留最后保存的图像savedImages

中的请求

现在我的代码如下:

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
    }
}

现在,savedImages仅在TOGGLE_SAVED运行两次且savedImages中的项目不会持续存在时填充,每次重新填充loadedImages时(通过GET请求)

注意:有效负载中返回的典型“图像”对象为: {id: 0, saved: Boolean}

1 个答案:

答案 0 :(得分:0)

我相信在您当前的减速器中,savedImages道具实际上是在使用对loadedImages的先前引用。

这就是为什么它仅在第二轮运行时有效的原因。您假定最初的loadedImages map()运行并完成,然后继续进行下一个道具,但事实并非如此。

可能有效的方法如下:

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)
                ]
            }