简体   繁体   中英

React redux: Update nested state's boolean with another nested array of objects by comparing IDs

I have following state:

merchant: [{
    title: "Setup",
    steps: [
    {id: "provider", done: false}, 
    {id: "api_key", done: false}
    {id: "client", done: false}
    ]
}]

and i want to update it with the following dataset

merchant: [{
    title: "Setup",
    steps: [
    {id: "provider", done: false}, 
    {id: "api_key", done: true}
    ]
}]

So that I end up with the following:

merchant: [{
    title: "Setup",
    steps: [
    {id: "provider", done: false}, 
    {id: "api_key", done: true}
    {id: "client", done: false}
    ]
}]

What would be the cleanest way to achieve this?

I've done something like this in my reducer, but it seems like a terrible idea based on the output I'm getting.

guide_progression: {
    ...state.guide_progression,
    merchant: state.guide_progression.merchant.map(stateGuide =>
        payload.user.guide_progression.merchant.map(userGuide =>
            userGuide.title === stateGuide.title &&
            {
                ...stateGuide,
                steps: stateGuide.steps.map(stateStep =>
                    userGuide.steps.map(userStep =>
                        userStep.id === stateStep.id &&
                        {
                            ...stateStep,
                            done: userStep.done
                        }
                    )
                )
            }
        )
    )
}

Really appreciate suggestions for how to solve this. I've been struggling to find a good solution on the web.

You can use Immer , It allows you to

Create the next immutable state tree by simply modifying the current tree

Basically allows you to modify your data while keeping it immutable.

So immer is straight up amazing. Thanks ahmed mahmoud. Here's the solution I ended up with using immer.js

updateMerchantState = produce(state.guide_progression.merchant, draft => {
    payload.user.guide_progression.merchant.map(userGuide => {
        const guideIndex = draft.findIndex(guide => guide.title === userGuide.title)
        if (guideIndex !== -1) {
            userGuide.steps.map(userStep => {
                const stepIndex = draft[guideIndex].steps.findIndex(step => step.id === userStep.id)
                if (stepIndex !== -1) draft[guideIndex].steps[stepIndex].done = userStep.done
            })
        }
    })
})

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM