Настройка вложенного массива в контексте реакции

#reactjs #react-context #react-state #react-state-management

Вопрос:

Я пытаюсь понять, как обновить массив, вложенный в контекст React. Ниже приведен контекст, с которым я работаю. Он состоит из «списков». Каждый список содержит массив «элементов».

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

Я пытался изменить вложенные массивы, используя метод «setLists» ниже, но он не работает. Что я здесь делаю не так?

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

Комментарии:

1. Пожалуйста, никогда не публикуйте фотографии кода. Почтовый индекс в виде текста .

2. Подробнее о «…но это не работает» — как это не работает? Есть ли какая-то ошибка? Есть ли неожиданное поведение? Где вы вызываете removeListItem()? И т.д.

3. Прости! Вложенные массивы не меняются. Я могу обновить вложенные массивы в «PrevList», но когда обновленный предварительный список возвращается из метода setLists, изменения не отображаются в браузере.

4. Вам нужно вернуть совершенно новый массив. React знает об изменении только в том случае, если изменилась ссылка на массив. Клонируйте prevList с const clone = [...prevList] помощью, а затем мутируйте этот клон вместо этого и обязательно верните его. То же самое касается вложенных массивов или объектов. Реагируйте только тогда, когда меняются примитивы или ссылки.

5. Я изменил заявление о возврате на: return [...prevList]; и это сработало как заклинание. Спасибо!

Ответ №1:

Как отметил @zero298 в своем комментарии, вам нужно передать весь список в функцию обновления состояния setLists . Вы инициализируете состояние и его функцию обновления с помощью «списка словарей», поэтому вам нужно продолжать относиться к нему как к таковому, вы не можете выборочно изменять несколько свойств внутри словаря или несколько элементов в списке без необходимости обновлять весь список.

Простая коррекция вашего кода будет заключаться в том, чтобы условно создать новую копию вашего списка с обновленными значениями, а затем установить этот список в качестве вашего нового состояния с помощью функции обновления состояния.

Ура!

Комментарии:

1. Похоже, ты прав. Я изменил оператор return для setLists на return [...prevList]; , и браузер отображается правильно. Спасибо!