Реагирует на обновление массива useState

#reactjs #setstate #react-functional-component

#reactjs #setstate #реагирует-функциональный-компонент

Вопрос:

Я пробовал несколько вещей, но я не могу вообще обновить состояние этого массива. Я уверен, что я близок, но может кто-нибудь, пожалуйста, посмотрите и скажите мне, что я делаю не так. Спасибо

 const [totals, setTotals] = useState({
    1: 0,
    2: 0,
    3: 0,
    4: 0,
    5: 0,
    6: 0,
    7: 0,
    8: 0,
    9: 0,
    10: 0,
    11: 0,
    12: 0
});

const handleCalculations = (key, value) => {
    setTotals({
        ...totals,
        [key]:  totals[key]   value
    });
}
 

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

1. На первый взгляд мне кажется, что все в порядке. Можете ли вы показать, как вы подключаетесь handleCalculations ? Может value быть, это строка, поэтому вы путаете добавление с конкатенацией?

2. @kevin3954 вы описываете его как массив, но в коде показан объект, не являющийся массивом. Оба варианта возможны, но не могли бы вы уточнить, какой из них вы хотите?

3. Что именно пошло не так? Обновляется ли состояние вообще? Можете ли вы подтвердить, что он попадает в вашу handleCalculations функцию с ожидаемыми входными данными? (например, добавить a console.log )

4. Да, он попадает в функцию. В журнале консоли ключ и значение отображаются как целые числа. Однако ничего не обновляется вообще

5. Как вы подтвердили, что «ничего не обновляется»? Изучая пользовательский интерфейс? Я бы console.log(totals) сделал это прямо перед вашей return функцией, чтобы вы могли проверять исходное состояние при каждом повторном рендеринге. Кроме того, ваш исходный объект находится 1-12 в процессе рендеринга 0-11 , так что это может быть проблематично.

Ответ №1:

У меня есть подозрение, что вы вызываете handleCalculations неправильно. Скорее всего, вы используете его следующим образом

 <button onClick={handleCalculations}>click me</button>
 

В результате событие, которое является объектом, поступает в handleCalculations .

В результате ваше состояние становится таким:

 {
    1: 0,
    2: 0,
    3: 0,
    4: 0,
    5: 0,
    6: 0,
    7: 0,
    8: 0,
    9: 0,
    10: 0,
    11: 0,
    12: 0,
    12: 0,
    "[object Object]": null,
}
 

Попробуйте передать правильные параметры обработчику, например

 <button onClick={()=>handleCalculations(12,1)}>click me</button>
 

Это должно устранить проблему.

Подставьте параметры в функцию в соответствии с вашей логикой.

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

1. Этот ответ в некотором смысле правильный. Но что касается текущего кода, предоставленного @kevin3954, он переходит handeCalculations к Row компоненту. Итак, в этом компоненте он мог бы сказать: « <DateField date={date} bill={props.bill} index={index} paycheckFrequency={props.paycheckFrequency} handleCalculations={() => props.handleCalculations(12, 1)} /> «

2. @kevin3954, спасибо за ответ на ваш вопрос. Могу ли я попросить вас сделать минимальный воспроизводимый пример и опубликовать его на codesandbox.io ?

3. Я сделаю это. Спасибо за помощь. @Wilfred Mulenga, вы правы, что действительно обновляет значение. Однако мне нужно, чтобы он обновился значением, которое позже будет указано в дочернем элементе внутри useEffect . Значение 1 — это просто тестовое значение, чтобы посмотреть, смогу ли я его обновить. И ключ 12 также будет передан дочернему элементу. Возможно, я смотрю на это неправильно. Может быть, есть лучший способ сделать то, что я пытаюсь выполнить. Я довольно новичок в React. PHP — это мой фон. Я опубликую этот пример в codesandbox, чтобы посмотреть, смогу ли я сделать больше смысла. Спасибо всем

4. По Дрю Ризу вы передаете вычисления обработки в строку, которая передает его в DateField / TableCell в цикле, и TableCell вызывает его при монтировании компонента. Вы поставили в очередь кучу обновлений состояния в цикле, и все они обновляются из того же текущего состояния цикла рендеринга, в котором они поставлены в очередь. Решение Используйте обновление функционального состояния для постановки в очередь каждого обновления и каждое обновление из предыдущего вычисленного состояния, а не состояния из предыдущего цикла рендеринга. const handleCalculations = (ключ, значение) => { setTotals(итоги => ({… итоги, [ключ]: итоги [ключ] значение })); };