我有一个问题,当 React 组件的 props 改变时,它们不会重新渲染。 GroupLabel 将 counter 作为 prop。
export const GroupLabel = (props) => {
const change = () => {
props.setCurrent(props.group);
let newCounter = props.counter;
newCounter[props.group.ID] = 0;
props.setCounter(newCounter);
};
return (
<li className="person" onClick={change}>
<div className="user">
<img src="..."
</div>
<p className="name-time">
<span className="name">{props.group.name}</span>
</p>
{props.counter[props.group.ID]>0?<span className="badge badge-primary float-right">{props.counter[props.group.ID]}</span>:null}
</li>
);
}
GroupLabel 由其父组件为其组中的每个组调用(组是对象和状态的列表)。
{groups.length!==0?groups.map(item => {return <GroupLabel counter={counter} setCounter={setCounter} key={item.ID} setCurrent={setCurrent} group={item}/>}):null}
父组件中的 counter 是一个将 groupID 映射到该组通过 websocket 接收的消息数的对象。改成这样:
let newCounter = counter; // counter is a current state
newCounter[msgJSON.group]++; // msgJSON.group is id of group to which message is directed
setCounter(newCounter);
一切正常,但 React 仍然不重新渲染。根据我的阅读,React 应该在以下情况下重新渲染其组件:
-
他们的状态发生变化
-
他们的道具改变了
-
父组件被重新渲染
在这种情况下,GroupLabel 属性都会发生变化,父状态也会发生变化(因为它传递的计数器是他的状态)。我可以在 React Dev Tools 中看到 counter prop 已经改变(最初每个组都为零)。
我没有给出父组件的完整代码,因为它太长了。
问题是你正在改变状态,而不是创建一个新状态。当你在函数组件中设置状态时,react 会执行===
旧状态和新状态之间。如果它们相等,则组件不会渲染。
要解决此问题,请更改以下内容:
let newCounter = props.counter;
newCounter[props.group.ID] = 0;
props.setCounter(newCounter);
To this:
let newCounter = {
...props.counter
};
newCounter[props.group.ID] = 0;
props.setCounter(newCounter);
和这个:
let newCounter = counter;
newCounter[msgJSON.group]++;
setCounter(newCounter);
To this:
let newCounter = {
...counter;
}
newCounter[msgJSON.group]++;
setCounter(newCounter);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)