@awenn2015
Веб-программист самоучка

Почему я вижу изменения стейта сразу после его обновления?

не помню что бы раньше был такой эффект, допустим есть компонент

type DTEnum = "start" | "finish"
type ChangeDateTime = (type: DTEnum, value: string, index: number) => void

const defData = [] // Набор обьектов с каким то данными

const WorkTable: FC = () => {
  const [data, setData] = useState(defData)

// Функция в которой мы меняем стейт
 const changeDT: ChangeDateTime = (type, value, index) => {
    console.log(data[0].start)
    setData((prev) => {
      prev[index][type] = value
      return prev
    })
    console.log(data[0].start)
  }
// Где то там вызывается хандлер
return (<div onChange={changeDT}></div>)
}


Так вот, обычно что бы отловить измененный стейт я использовал и использую

useEffect(() => {
// Какие то действия
}, [data])


но useEffect почему то не вызываеться и я вижу уже измененный стейт прямо в хандлере, думал что дело в том что я меняю через prev но не помню что бы раньше было такое же поведение, первый раз такое вижу
  • Вопрос задан
  • 73 просмотра
Решения вопроса 1
@Habr_Agent
При обновлении состояния в React, изменения не всегда отображаются мгновенно, а зависят от реализации механизма обновления. Ваш случай может быть связан с тем, что React может объединять несколько обновлений состояния в одно, если они происходят в рамках одной функции-обработчика, как в вашем примере.

Поэтому, когда вы вызываете console.log(data[0].start) сразу после обновления состояния, вы можете видеть как "старое" значение, а не обновленное. Но, если вы вызовете console.log(data[0].start) внутри useEffect с зависимостью [data], то это должно отобразить обновленное значение.

Если вы хотите выполнить какие-то действия после изменения состояния, то лучше всего использовать useEffect с зависимостью от состояния. В вашем случае, измените обработчик следующим образом:
const changeDT: ChangeDateTime = (type, value, index) => {
  setData((prev) => {
    const newData = [...prev];
    newData[index][type] = value;
    return newData;
  });
}

useEffect(() => {
  console.log(data[0].start);
}, [data]);

В этом примере мы клонируем массив данных, изменяем нужное значение и возвращаем обновленный массив. Затем, используем useEffect для выполнения дополнительных действий после обновления состояния.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы