Реакция: массив useState не обновляется

#javascript #reactjs #typescript #use-state

#javascript #reactjs #typescript #use-state

Вопрос:

Когда вы вводите массив, данные передаются. Однако, если вы зарегистрируетесь в console.log, данные не будут импортированы. Похоже, это задержка. Можете ли вы сказать мне, почему это происходит?

есть ли решение для этого?

Ожидаемая консоль.результат журнала показывает ввод, однако отображается пустой массив, и если вы снова нажмете флажок, появится ввод.

 
  const [checked, setChecked] = useState<number[]>([])

  const handleAddListToArray = (id: number) => {
    console.log(checked)
    if (setChecked.includes(id)) {
      setChecked(checked.filter((item) => item !== id))
    } else {
      setChecked([...checked, id])
    }
  }

--- checkbox compornent ---

  const [isChecked, setIsChecked] = useState(false)

  const handleChange = () => {
    setIsChecked(!isChecked)
    handleAddListToArray(id)
  }

 <Checkbox checked={isChecked} onClick={() => handleChange()} />


 

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

1. Возможно, вам нужно сделать это if (checked.includes(id)) вместо этого if (setChecked.includes(id)) . Подробнее я могу ответить, если вы напишете свой полный код компонента

Ответ №1:

однако, когда вы вводите массив, данные передаются, если вы регистрируетесь в консоли.данные журнала не передаются. похоже, это задержка, можете ли вы сказать мне, почему это происходит?

Функции настройки состояния являются асинхронными. Другими словами, если вы написали:

 const [foo, setFoo] = useState(0);
setFoo(1);
console.log(foo); // logs 0, NOT 1
 

вы бы увидели 0 logged, а не 1 … по крайней мере, на начальном этапе. Однако ниже будет показана запись в журнале 1 .

Это связано с тем, что set* function не изменяет значение в функции, но они вызывают повторный рендеринг компонента после, что означает, что функция запускается снова и теперь использует правильное значение..

однако отображается пустой массив, и если вы снова нажмете флажок, появится ввод.

Это из-за этого кода:

 setIsChecked(!isChecked)
 

Изначально вы устанавливаете isChecked значение в массив:

 setChecked(checked.filter((item) => item !== id))
 

Но затем вы изменили его на !isChecked логическое значение. Как только вы измените его на логическое значение, вы не сможете изменить его обратно на массив.

Ответ №2:

Вы проверяете setState-функцию, если она включает входные данные, в четвертой строке кода:

 if (setChecked.includes(id))
 

Я полагаю, что вместо этого вы хотите проверить проверенное состояние, например:

 if (checked.includes(id))
 

Кроме того, рассмотрите возможность использования обратного вызова useState при изменении вашего состояния на основе предыдущего. Поэтому вместо:

 setChecked(checked.filter((item) => item !== id))
 

попробуйте:

 setChecked((prevState) => prevState.filter((item) => item !== id))
 

Вы также можете использовать это при настройке состояния IsChecked. Это гарантирует, что вы получите свое последнее известное состояние и избежите попадания в некоторые странные состояния, потому что React обновляет состояние асинхронно.

Ответ №3:

Некоторые предложения

 if (setChecked.includes(id)) {
 

должно быть (setChecked — это функция)

 if (checked.includes(id)) {
 

Для setChecked(checked.filter((item) => item !== id))

лучшее использование будет

 setChecked(prevCheckedValues => prevCheckedValues.filter((item) => item !== id));
 

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

Другой способ использовать это — использовать обратный вызов и передать массив зависимостей как [checked]

Если вы хотите печатать checked значения каждый раз при его изменении, вы можете использовать useEffect (docs) с правильным массивом зависимостей.

Пример использования

 useEffect(()=>{
   console.log("Checked", checked);
}, [checked])