【问题标题】:Do we still need functional setState way in react hooks?我们还需要在反应钩子中使用功能性的 setState 方式吗?
【发布时间】:2019-08-25 21:24:49
【问题描述】:
  const [count, setCount] = useState(0);

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

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

来自基于类的组件背景,它成为我们使用函数式setState的习惯。我想知道我们是否还需要在功能挂钩中依赖 prevState?或者当前状态总是“可信任”且最“更新”的?

【问题讨论】:

标签: javascript reactjs react-native react-hooks


【解决方案1】:

是的,行为类似。

React 正在批处理更新调用。 写作时:

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

count 的状态将为 1

写作时:

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

count 的状态为 3

【讨论】:

  • 谢谢,这个例子很清楚它是如何工作的。这解释了为什么我的组件中的切换功能在尝试逻辑上不是存储在状态中的布尔值时无法正常工作。
【解决方案2】:

State updater function 在类和函数组件中都是必需的。 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)
}, []);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2011-12-22
    相关资源
    最近更新 更多