Есть ли синхронная альтернатива setState () в Reactjs функциональных компонентах - PullRequest
2 голосов
/ 29 мая 2020

Я знаю, как это сделать в компонентах класса, но когда я использую тот же код в функциональном компоненте, я получаю сообщение об ошибке. Это то, что я хочу -

this.setState({cnt:this.state.cnt+1})
alert(this.state.cnt);

теперь я хочу, чтобы в предупреждении отображалось значение 1. Как мы это делаем в компоненте класса -

this.setState({cnt:this.state.cnt+1}, () => alert(this.state.cnt));

Но когда я делаю то же самое в функциональном компоненте, например,

const[count, setCount] = useState(0);
setCount(count+1, () => alert(count));

, я получаю сообщение об ошибке - «не ожидал, что нет». аргументов - 1 ".

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

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

const [count, setCount] = useState(0);

useEffect(() => {
  alert('count updated!);
}, [count]);
2 голосов
/ 29 мая 2020

Программа обновления состояния с перехватчиками реакции не обеспечивает обратный вызов. Вам нужно использовать useEffect, чтобы добиться такого же поведения. Кроме того, поскольку вы хотите, чтобы useEffect запускался только при обновлении, вы можете отключить его начальное выполнение с помощью useRef

setCount(prev => prev+1);
...
const initialRender = useRef(true);
useEffect(() => {
   if(!initialRender.current) {
     alert(count);
   } else {
     initialRender.current = false;
   }
}, [count]);

В некоторых случаях вы можете не захотеть, чтобы useEffect запускался при обновлении счетчика, а только когда счетчик обновляется из специальной функции. В таких случаях вы можете использовать useRef

const runEffect = useRef(false);
const initialRender = useRef(true);
useEffect(() => {
   if(!initialRender.current) {
     // This will only be executed when you toggle ref

     alert(count);
   } else {
     initialRender.current = false;
   }
}, [runEffect.current]);
// adding ref as a dependency is fine here since we know that a re-render will be triggered by setCount


someFunction = () => {
   setCount(prev => prev + 1);
   runEffect.current = !runEffect.current;
}
...