【问题标题】:When using useState hook - Is there an importance to changing the setState functions call order?使用 useState 挂钩时 - 更改 setState 函数调用顺序是否重要?
【发布时间】:2019-11-23 10:41:03
【问题描述】:

我有一个带有两个状态变量(itemsDataitemsCollections)的 React 功能组件。变量在useEffect 方法中更新。但是在useEffect 发生之后,状态变量之一是null

在切换 setStateFunctions (setItemsData & setItemsCollect) 调用顺序时,两个参数都按预期初始化。

怎么样?

const MyComponent = ({itemsIds}) => {
   const [itemsData, setItemsData] = useState([]);
   const [itemsCollections, setItemsCollect] = useState({});

 useEffect(() => {
        fetchItemsData({ itemsIds }).then(({ items, itemCollect }) => {
             setItemsData(items);
             setItemsCollect(itemCollect);
        })
    }, [itemsIds]);
...
console.log('itemsData', itemsData) // the expected array
console.log('itemCollect', itemCollect) // empty objecy

useEffect后的状态:itemCollect = {}, itemsData = [{value:...},...]

切换调用顺序:

const MyComponent = ({itemsIds}) => {
   ...
 useEffect(() => {
        fetchItemsData({ itemsIds }).then(({ items, itemCollect }) => {
             setItemsCollect(itemCollect); // <--> switched rows
             setItemsData(items); // <--> switched rows

        })
    }, [itemsIds]);
...
console.log('itemsData', itemsData) // the expected array
console.log('itemCollect', itemCollect) // the expected object

useEffect 后的状态:itemCollect = { someValue: ...} , itemsData = [{value:...},...]

【问题讨论】:

标签: javascript reactjs react-hooks


【解决方案1】:

有一个称为批处理的性能优化,can change between React versions。应用此优化时,多个setState 调用将在下一次渲染之前一起批处理(顺序无关紧要)。

如果未应用(例如,在您的情况下的 Promise 中,请参阅 Does React batch state update functions when using hooks?),则每次状态更新都会触发新的渲染(并且顺序很重要)。

=> console.log('itemCollect', itemCollect) 可能会在每次渲染中记录不同的数据。

如果您需要强制更新单个状态,那么从 useReducer 调用单个调度可能是最佳选择。

【讨论】:

  • 谢谢,您的回答解释了部分行为,但缺少的部分是为什么更改行会改变结果。因此,我继续研究调用之间的差异,似乎在第一种情况下,render 被触发了两次,但是当我切换行时,render 只被触发了一次。这意味着在 Promise 中没有实现批处理的假设是错误的。我猜触发一次或两次的原因是变量的大小。 “items”是一个包含许多元素的大数组,“itemCollect”是一个带有一个键的小对象。
  • 如果您将更新您的答案以更准确并回答主要问题(意思是 - 是的,不同的调用顺序可以改变触发渲染的数量)我很乐意接受它 -
  • 我无法验证您如何检测渲染次数的方法,并且我没有其他消息来源相信渲染次数可能取决于单个堆栈帧中函数调用的顺序。我可能会检查 React 源代码,但在那之前,我将无法用任何更多经过验证的事实来更新我的答案。不过,请随意发布您自己的答案以及您的发现。
猜你喜欢
  • 2021-05-26
  • 2019-08-07
  • 1970-01-01
  • 2020-03-12
  • 2019-11-29
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
相关资源
最近更新 更多