【问题标题】:Why does setting useState inside a loop perform differently?为什么在循环内设置 useState 执行不同?
【发布时间】:2020-10-20 05:28:01
【问题描述】:

有人可以向我解释一下下面的代码 sn-p 吗?为什么handleClick() 不能正常工作(只设置了newData 的1 或2 个数据属性)而handleClick2() 工作正常。

我猜测问题是由于循环造成的(因为这是唯一的区别),但为什么循环会导致这种效果?

沙盒链接:https://codesandbox.io/s/restless-surf-u9i5s?file=/src/App.js:0-969

import React, { useState, useEffect } from "react";
import "./styles.css";


const App = () => {
  const [newData, setNewData] = useState({
    data1: '',
    data2: '',
    data3: '',
    data4: ''
  })

  const handleClick = () => {
    let fields = ['data1', 'data2', 'data3', 'data4']
    let field
    for (field of fields) {
        setNewData(oldState => ({...oldState, [field]: 'test'}))
    }
  }

  const handleClick2 = () => {
    setNewData(oldState => ({...oldState, data1: 'test'}))
    setNewData(oldState => ({...oldState, data2: 'test'}))
    setNewData(oldState => ({...oldState, data3: 'test'}))
    setNewData(oldState => ({...oldState, data4: 'test'}))
  }

  useEffect(() => {
    console.log('State: ' + JSON.stringify(newData))
  }, [newData])

  return (
    <div className="App">
      <button onClick={handleClick}>Click</button>
      <button onClick={handleClick2}>Click2</button>
    </div>
  );
}

export default App

【问题讨论】:

    标签: reactjs react-hooks react-state use-state


    【解决方案1】:

    原因是:

    setNewData 是异步函数。当你以某种方式调用setNewData 时,React 会在事件循环中推送它的回调函数,然后在主线程为空时在主线程中调用它。当setNewData 回调函数在main 中调用时,fieldtest4,因为for (field of fields) 同步函数。 ==> 只有setNewData(oldState =&gt; ({...oldState, data4: 'test'})) 被调用了 4 次。

    您可以在setNewData 回调函数中记录field 并查看它的值。

    for (field of fields) {
      console.log(field)
      setNewData(oldState => {
        console.log(field)
        return { ...oldState, [field]: "test" }
      })
    }
    

    Codesandbox for it

    【讨论】:

    • 谢谢。但是,循环它与并排运行 4 个调用有什么区别呢?
    • 当你并排调用4个调用时,例如setNewData(oldState =&gt; ({...oldState, data1: 'test'}))等,它们不依赖于field。当他们每个人在主线程中被回调时,js 知道data1: "test" NOT [field]: "test"
    • 完美!谢谢你的解释!
    猜你喜欢
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多