Do we still need functional setState way in react hooks?

后端 未结 2 492
没有蜡笔的小新
没有蜡笔的小新 2020-12-17 00:22
  const [count, setCount] = useState(0);

  const handleClick = () =>
    setCount(prevCount => {
      return prevCount         


        
相关标签:
2条回答
  • 2020-12-17 00:30

    State updater function is necessary in both class and functional components. this.setState shouldn't be used together with this.state, the same applies to useState state and state setter. There are more cases for useState when not using state updater will result in wrong behaviour.

    In class components, the only problem with the use of this.state is race condition due to asynchronous state updates:

    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
    }
    

    When there are no race conditions, this.state can be accessed anywhere inside a component because this reference stays the same:

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

    In functional components, the problem with the use of useState state is function scope. There's no object like this that could be accessed by reference, a state is accessed by value which won't be updated until a component is re-rendered:

    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)
    }, []);
    
    0 讨论(0)
  • 2020-12-17 00:41

    Yes, the behavior is similar.

    React is batching the updates calls. When Writing:

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

    the count in state will be 1

    When Writing:

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

    the count in state will be 3

    0 讨论(0)
提交回复
热议问题