我正在react/react hooks中编写一段代码,尝试执行以下操作。
从父组件获取对象数组作为 prop
使用将其设置为状态useState
钩。
根据预期的过滤器(时间和评级)对状态进行排序,然后重新渲染子组件。
我看到的是,下面的代码在排序后更新了状态,但即使更新了状态,依赖于状态的子组件也不会重新渲染。我认为只要状态改变,子组件就会自动重新渲染?
import React, {useState} from 'react';
import ProfilePostspreview from './ProfilePostspreview';
function ProfileNavigation(props){
const [newarray, setnewarray]=useState(props.parray); //'parray' object passed as props and saved as 'newarray' state
const otc = () => { //Function to sort the state by time and set a new state
let k=newarray;
setnewarray(k.sort((a, b) => (a.time > b.time) ? -1 : 1 ));
}
const orc = () => { //Function to sort the state by rating and then time and set a new state
let k=newarray;
setnewarray(k.sort((a, b) => (a.rating > b.rating) ? -1 : (a.rating === b.rating) ? ((a.time > b.time) ? -1 : 1) : 1 ));
}
return (
<div>
<div className="sm_options"> //Component to trigger the otc and orc functions
<div className="sm_button" id="order_t" onClick={otc}>Sort by time</div>
<div className="sm_button" id="order_r" onClick={orc}>Sort by rating</div>
</div>
<div className="posts_preview_columns_p"> //This is dependent on the 'newarray' state but is not re-rendering even after the state is sorted and updated?
{newarray.map(na=>
<ProfilePostspreview
postThumbnail={na.photolink}
rating={na.rating}
time={na.time}
target={na.target}
/>
)}
</div>
</div>
);
}
export default ProfileNavigation;
这可能是什么原因?代码是否有问题,或者状态排序是否被认为不够强大,不足以让 React 重新渲染子组件?如果是后者,如何在排序后强制重新渲染?
有什么建议吗?谢谢!
数组::排序 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
The sort()
方法对数组的元素进行就地排序并
返回排序后的数组。默认排序顺序是升序,构建
将元素转换为字符串,然后比较它们
UTF-16 代码单元值的序列。
这对您来说意味着存储在数组中的元素的顺序可能会改变,但数组会就地排序,这意味着返回相同的数组引用(与返回的其他数组函数不同)new数组)。
React 协调是通过检查状态和 props 进行的,并做出一个整体假设:如果下一个状态/prop 引用没有改变,那么值也没有改变,从而返回最后计算的渲染 DOM。这是更新反应状态的重要细节......每次更新都需要引用一个新对象。
就你而言,你只是saving的参考current状态数组,改变它,然后重新保存它。由于引用是稳定的并且不会改变,因此反应不会重新渲染。
const otc = () => {
let k = newarray; // <-- saved array reference!!
setnewarray(k.sort((a, b) => (a.time > b.time) ? -1 : 1 ));
}
正确的反应方式是复制当前数组值into a new数组,因此它将有一个新的对象引用。
const otc = () => {
const newSortedArray = [...newArray].sort(
(a, b) => (a.time > b.time) ? -1 : 1
); // spread old array values into new array, then sort
setNewArray(newSortedArray);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)