状态更新后 React 不刷新(对象数组)
Posted
技术标签:
【中文标题】状态更新后 React 不刷新(对象数组)【英文标题】:React does not refresh after an update on the state (an array of objects) 【发布时间】:2020-05-26 08:41:08 【问题描述】:我在我的州显示带有地图功能的cards
。
状态如下所示:
[ position: "0", state: "pending" ,
position: "1", state: "pending" ,
position: "2", state: "pending" ]
在一个函数中,我将“状态”从“待处理”更改为“正确”,但它不会刷新页面上的任何内容。
export const Card: React.FC<ICardOwnProps> = ( ) =>
const [rollingCards, setRollingCards] = useState<IRollingCard[]>([ position: "0", state: "pending" , position: "1", state: "pending" , position: "2", state: "pending" ])
const handleClick = () =>
let newArray = rollingCards;
newArray.splice(0, 1)
setRollingCards(newArray);
useEffect(() => console.log("check changes") )
return (
<StyledCard className="Card">
rollingCards.map((v, i, a) =>
<Container key=i className="position" + v.position >v.state</Container>
)
<div className="card__container--button">
<button onClick=handleClick>Oui</button>
<button>Non</button>
rollingCards[0].state
</div>
</StyledCard>
);
从现在开始,一切都没有改变,但是当我添加一个与 rollingCards 同时更新的新状态片段时,它会更新。我添加了一个计数器,然后它会更新页面。
(我也试过拼接数组看React会不会更新,没有)
知道我为什么会有这种奇怪的行为吗?
谢谢。
【问题讨论】:
【参考方案1】:这是因为 React 在决定重新渲染时会比较 props/state 的引用相等性。
newArray 与 rollingCards 具有相同的引用,因此功能组件不会在 setRollingCards 上重新呈现
改变
setRollingCards(newArray)
到
setRollingCards([...newArray])
这将使用 newArray 中的元素创建一个新数组(新引用)
工作解决方案: https://codesandbox.io/s/admiring-wave-9kgqq
【讨论】:
这是非常非常有用的。所以参照平等只是比较,不是深度比较的权利。只检查数组而不是元素在需要深度比较的对象中发生变化吗?【参考方案2】:因为 react 使用Object.is
来判断状态是否发生了变化。
在您的代码中,newArray
与rollingCards
引用相同,您可以使用Object.is(newArray, rollingCards)
进行检查。
const handleClick = () =>
let newArray = rollingCards;
newArray.splice(0, 1) // Object.is(newArray, rollingCards) is true
setRollingCards(newArray);
所以你可以这样改变它。
setRollingCards(rollingCards.filter((item, index) => index !== 0);
不只是这个方法,只要是不同的参考
【讨论】:
以上是关于状态更新后 React 不刷新(对象数组)的主要内容,如果未能解决你的问题,请参考以下文章
React - 使用 setState 更新状态中的对象数组