状态更新后 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 来判断状态是否发生了变化。

在您的代码中,newArrayrollingCards 引用相同,您可以使用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 更新状态中的对象数组

使用 React Hooks 更新状态数组的所有对象元素

react usestate 重新设置数据后,不渲染页面

React - 使用setState更新状态中的对象数组

React Hooks 表单处理:使用多个字符串项和一个数组项更新对象的状态

React Hook useState 视图不更新