如何解决反转存储在 State 中的数组不会强制重新渲染 React 中的组件
这是一个较大组件的一部分,但我已在下面的可重现示例中对其进行了总结:
import React,{useState} from 'react'
function App() {
const [data,setData] = useState([{name:'first'},{name:'second'},{name:'three'}])
// Function to reverse a given array
const reverseArray = (array) => {
var reverseArray = array.reverse();
return reverseArray;
}
return (
<div>
{data.map((item,index)=>{
return <h1 key={index}>{item.name} index: {index}</h1>
})}
{/*When I click this I expect the div above to rerender */}
<button onClick={()=>{
var newData = data;
setData(reverseArray(newData))}
}>
Reverse Order
</button>
{/* Logs state to the console to check order is reversed */}
<button onClick={()=>console.log(data)}>Log Data</button>
{/* Clearing the state by setting to empty array */}
<button onClick={()=>setData([ ])}>Clear Data</button>
</div>
)
}
所以我的主要问题是映射数据似乎不会随着状态更新而改变。 作为检查状态是否更新,我有一个清除按钮可以清除数据状态并且列表变为空白。
当我点击反转按钮时,我希望数据被反转(即“第一个”在最后,“三个”在第一个)。 我确定我的状态已更新,因为我可以在单击反向按钮之前和之后使用控制台日志检查它。
我的想法是创建一个全新的反向数组 (newData) 并将其设置为状态。但是,映射不反映此顺序更改。我在这里缺少什么?
我知道 React 中的组件会在 state 改变时重新渲染,为什么设置一个新数组来 state 不会触发这个?但是清除状态时重新渲染很明显?
我的沙箱:https://codesandbox.io/s/immutable-sun-oujqj?file=/src/App.js
解决方法
演示: https://codesandbox.io/s/array-reverse-react-state-0v67h
Array.prototype.reverse()
原地反转元素。您需要将一个新数组传递给 setData()
。
<button
onClick={() => {
var newData = data;
// Create a new array using the spread operator
setData(reverseArray([...newData]));
}}
>
,
React 没有重新渲染组件的原因是因为 Array.prototype.reverse
改变了数组并返回引用
例如
const array = [1,2,3,4,5]
const revArray = array.reverse() // This will reverse 'array' variable and returns it's reference
array === revArray // this statement is true
console.log(array) // result [5,1]
console.log(revArray) // result [5,1]
在上面的 array === revArray
中,因为两者都指向同一个数组,
既然如此,状态实际上并没有改变,因为对数组的引用是相同的。
解决方案: 只需返回一个新数组即可!
const reverseArray = (array) => {
const revArray = array.reverse();
return [...revArray]
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。