Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React useState hook变量的破坏性排序?_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript React useState hook变量的破坏性排序?

Javascript React useState hook变量的破坏性排序?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,这个组件的一个支柱是一个值数组,我想对这些值进行排序。我已经通过以下方式做到了这一点: const MyComponent=items=>{ 常量[sortedItems,setSortedItems]=useState(项) useffect(()=>sortedItems.sort(),[sortedItems]) /*组件代码的其余部分*/ } 这显然似乎不符合React和Hooks的精神,但它确实有效。我不是在寻找替代的实现方法,但我非常好奇的是:这里的方法是否由React文档指示 R

这个组件的一个支柱是一个值数组,我想对这些值进行排序。我已经通过以下方式做到了这一点:

const MyComponent=items=>{
常量[sortedItems,setSortedItems]=useState(项)
useffect(()=>sortedItems.sort(),[sortedItems])
/*组件代码的其余部分*/
}
这显然似乎不符合React和Hooks的精神,但它确实有效。我不是在寻找替代的实现方法,但我非常好奇的是:这里的方法是否由React文档指示

React文件是否指示此处的进近计数器

对。通常情况下,更新状态应该调用其setState函数,但我们在这里看到,使用
sort
会在不调用
setSortedItems
的情况下变异
sortedItems
。使用
setSortedItems
的方法可以如下实现:

useEffect(() => setSortedItems([...sortedItems].sort()), [sortedItems])
(我知道你说不要寻找替代方法,但请以此为例,我可以解释。)

重要的一点是,在触发渲染之前,这不会改变先前的
sortedItems
。这样,下一个DOM渲染和读取
sortedItems
的任何地方都将保持一致


更新 尽管对
sortedItems
的呈现和访问是一致的,但由于React的状态更新是异步排队的,因此它可能不包含后续更新中预期的值(此问题在OP的示例中也很普遍)。当对后续的
sortedItems
进行排序的时间差异很大时,就会出现问题,但也可能有其他原因

React文档在其文档中为
setState
解释此行为:

后续调用将覆盖同一周期中以前调用的值,因此数量只增加一次。如果下一个状态取决于当前状态,我们建议使用updater函数表单,而不是:

this.setState((state) => {
   return {quantity: state.quantity + 1};
});
在我们的示例中,这是向示例中添加回调的一个小改动:

useEffect(() => setSortedItems((prevSortedItems) => [...prevSortedItems].sort()), [sortedItems])

这与React的协调算法的工作原理背道而驰<代码>排序是一个变异过程,
sortedItem
更改不会(或至少不应该)在其自身的过程中触发重新排序。通常情况下,状态中的变化(一件非常糟糕的事情)看起来像是在工作,因为父级触发了重新渲染器,并且变化向下传播到相关组件。它是巧合地重新命名的,而不是其自身操作的直接后果。我建议将
setSortedItems([…sortedItems].sort())
更改为类似这样的内容:
setSortedItems(previousItems=>[…previousItems].sort())
。由于将异步处理
setSortedItems
,因此可能会发生
sortedItems
在访问和设置实际设置之间被修改的情况。更新的答案:)