反转存储在 State 中的数组不会强制在 React 中重新渲染组件
Reversing an array stored in State doesnt force re-render of component in 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 中的组件会在状态改变时重新渲染,为什么设置一个新的状态数组不会触发这个?但是清除状态时重渲染很明显?
我的沙箱: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
改变了数组和 return 引用
例如
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,4,3,2,1]
console.log(revArray) // result [5,4,3,2,1]
在上面array === revArray
因为两者都指的是同一个数组,
既然如此,状态实际上并没有改变,因为对数组的引用是相同的。
解法:
只需 return 一个新数组!
const reverseArray = (array) => {
const revArray = array.reverse();
return [...revArray]
}
这是一个更大组件的一部分,但我在下面的可重现示例中对其进行了总结:
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 中的组件会在状态改变时重新渲染,为什么设置一个新的状态数组不会触发这个?但是清除状态时重渲染很明显?
我的沙箱: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
改变了数组和 return 引用
例如
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,4,3,2,1]
console.log(revArray) // result [5,4,3,2,1]
在上面array === revArray
因为两者都指的是同一个数组,
既然如此,状态实际上并没有改变,因为对数组的引用是相同的。
解法: 只需 return 一个新数组!
const reverseArray = (array) => {
const revArray = array.reverse();
return [...revArray]
}