Реагировать - использовать состояние доступа перехватчика useState - PullRequest
3 голосов
/ 13 января 2020

У меня есть следующие состояния:

let [currentMonth, setCurrentMonth] = useState(new Date().getMonth());
const [checkIn_month, setCheckInMonth] = useState(null);

У меня click event listener назначено напрямую на JSX's элемент tbody. Используя event delegation, нажмите на td elements.

И в следующей функции, если я нажму на день, который находится в в предыдущем месяце , мне нужно уменьшить значение currentMonth state и после этого для установки нового значения currentMonth в состоянии setCheckInMonth.

Проблема :

Когда я использую состояние setCheckInMonth(currentMonth), перехватите его дает старое значение, а не новое.

let [currentMonth, setCurrentMonth] = useState(new Date().getMonth());
const [checkIn_month, setCheckInMonth] = useState(null);

const selectDate = e => {

 if (e.target.tagName === 'TD') {

   if (e.target.classList.contains('previous-month-day')) {
    setCurrentMonth(currentMonth => currentMonth - 1);
    setCheckInMonth(currentMonth);
   }
  }
}

Что если я сделаю что-то вроде этого:

setCurrentMonth(currentMonth => currentMonth - 1);
setCheckInMonth(currentMonth - 1);

Это правильный способ сделать это?

Ответы [ 2 ]

2 голосов
/ 13 января 2020

setState() является асинхронным . Это не немедленно мутирует (обновляет) объект. Таким образом,

setCurrentMonth(currentMonth => currentMonth - 1);

не означает, что currentMonth имеет обновленное значение, которое вы можете немедленно использовать в следующей строке.

То, что вы можете сделать, -

const newCurrentMonth = currentMonth - 1;
// now use this newCurrentMonth to update the state.
setCurrentMonth(newCurrentMonth );
setCheckInMonth(newCurrentMonth );
0 голосов
/ 13 января 2020

Если вы хотите обновить checkIn_month, используя текущее значение currentMonth, вы не можете рассчитывать на немедленное обновление значения currentMonth, поскольку setState вызовы асинхронные. Вместо этого вы можете переместить ваш вызов на setCheckInMonth в пределах обратного вызова, переданного на setCurrentMonth, чтобы у вас был доступ к текущему значению currentMonth.

Например:

setCurrentMonth(currentMonth => {
    const newCurrentMonth = currentMonth - 1;
    setCheckInMonth(newCurrentMonth);
    return newCurrentMonth;
});
...