Нам все еще нужен функциональный метод setState в реагирующих хуках? - PullRequest
1 голос
/ 04 апреля 2019
  const [count, setCount] = useState(0);

  const handleClick = () =>
    setCount(prevCount => {
      return prevCount + 1;
    });
  const [count, setCount] = useState(0);

  const handleClick = () => setCount(count + 1);

Исходя из основанного на классах компонента, это становится привычкой, когда мы используем функционал setState. Мне интересно, нужно ли нам полагаться на prevState в функциональных хуках? Или текущее состояние всегда "надежное" и наиболее "обновленное"?

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Да , поведение аналогичное.

React пакетирует вызовы обновлений.При записи:

const handleClick = () => setCount(count + 1)
handleClick()
handleClick()
handleClick()

count в состоянии будет 1

При записи:

const handleClick = () =>
  setCount(prevCount => {
    return prevCount + 1;
});
handleClick()
handleClick()
handleClick()

count в состоянии будет 3

0 голосов
/ 04 апреля 2019

Функция обновления состояния необходима как для класса, так и для функциональных компонентов.this.setState не следует использовать вместе с this.state, то же самое относится к useState состоянию и установщику состояний.В useState есть еще случаи, когда не используется средство обновления состояний, что приведет к неправильному поведению.

В компонентах класса единственной проблемой при использовании this.state является состояние гонки из-за асинхронных обновлений состояния:

componentDidMount() {
  this.setState({ count: this.state.count + 1 });
  this.setState({ count: this.state.count + 1 }); // overwrites with stale count
  console.log(this.state.count); // not updated
}

Когда нет условий гонки, можно получить доступ к this.state в любом месте внутри компонента, поскольку ссылка this остается неизменной:

componentDidMount() {
  this.setState({ count: this.state.count + 1 });

  setTimeout(() => {
    this.setState({ count: this.state.count + 1 });
  }, 100)

  setTimeout(() => {
    console.log(this.state.count);
  }, 200)
}

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

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

useEffect(() => {
  // runs once on mount
  // count is always 0 in this function scope

  setCount({ count: count + 1 });

  setTimeout(() => {
    setCount({ count: count + 1 }); // overwrites with stale count
  }, 100)

  setTimeout(() => {
    console.log(count); // not updated
  }, 200)
}, []);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...