@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 но не помню что бы раньше было такое же поведение, первый раз такое вижу
  • Вопрос задан
  • 68 просмотров
Решения вопроса 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 для выполнения дополнительных действий после обновления состояния.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы