0

I am trying to figure out how to update an array that is nested within a React Context. Below is the context I am working with. It consists of "lists". Each list contains an array of "items".

import React, {useState, createContext} from 'react';

export const ListerContext = createContext();

export const ListerProvider = (props) => {


    const [lists, setLists] = useState([
        {
            id: 1,
            items: [{ 
                    itemid: 1,
                    text: 'Hello'
                },
                { 
                    itemid: 2,
                    text: 'world'
                }]
        },
                {
            id: 2,
            items: [{ 
                    itemid: 2,
                    text: 'Test'
                }]
        }
    ]);


    return(
        <ListerContext.Provider value={[lists, setLists]}>
            { props.children }
        </ListerContext.Provider>
    );
}

I have been trying to change the nested arrays using the "setLists" method below but it is not working. What am I doing wrong here?

const removeListItem = (e) => {
    setLists((prevList)=>{
        for(var i = 0; i < prevList.length; i++){
            if(prevList[i].id === parseInt(e.target.value[2])){
                prevList[i].items = (prevList[i].items.filter(function(item) {
                    return item.itemid !== parseInt(e.target.value[0]);  
                }))
            }
        }
        return prevList;
    });
}
5
  • Please, don't ever post pictures of code. Post code as text. Commented Aug 2, 2021 at 20:37
  • Elaborate on "...but it is not working" - how is it not working? Is there an error? Is there unexpected behavior? Where are you calling removeListItem()? Etc. Commented Aug 2, 2021 at 20:40
  • Sorry! The nested arrays are not changing. I am able to update the nested arrays within "prevList" but when the updated prevList is returned from the setLists method the changes are not being rendered to the browser. Commented Aug 2, 2021 at 20:49
  • 2
    You need to return an entirely new array. React only knows there is a change if the array reference has changed. Clone prevList with const clone = [...prevList] and then mutate that clone instead and be sure to return it. Same thing for nested arrays or objects. React only know when primitives or references change. Commented Aug 2, 2021 at 20:55
  • I changed the return statement to: return [...prevList]; and it worked like a charm. Thank you! Commented Aug 3, 2021 at 1:40

1 Answer 1

1

As @zero298 mentioned in their comment, you need to pass the entire list into your state update function setLists. You are initializing the state and its update function with a "list of dictionaries", so you need to keep treating it as such, you can't selectively change few properties inside the dictionary or few elements in the list without having to update the entire list.

Easy correction of your code will be to conditionally make a new copy of your list with updated values, and then setting that list as your new state using your state update function.

Cheerio!

Sign up to request clarification or add additional context in comments.

1 Comment

Looks like you are right. I changed the return statement for setLists to return [...prevList]; and the browser rendered properly. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.