javascript - 当某个道具发生变化时,如何避免重新渲染功能组件?
问题描述
我有一个 PlayArea 组件,其中包含许多 Card 组件作为子组件,用于纸牌游戏。
牌的位置由 PlayArea 管理,它有一个名为 的状态值cardsInPlay
,它是一个CardData
对象数组,包括位置坐标等。PlayArea 将cardsInPlay
and setCardsInPlay
(from useState
) 传递到每个 Card 子组件中。
卡片是可拖动的,在拖动时它们会调用setCardsInPlay
以更新自己的位置。
结果当然是cardsInPlay
改变了,因此每张卡片都会重新渲染。如果一百张牌出现在桌面上,这可能会增加成本。
我怎样才能避免这种情况?PlayArea 和 Card 都是功能组件。
这是该描述的简单代码表示:
const PlayArea = () => {
const [cardsInPlay, setCardsInPlay] = useState([]);
return (
<>
{ cardsInPlay.map(card => (
<Card
key={card.id}
card={card}
cardsInPlay={cardsInPlay}
setCardsInPlay={setCardsInPlay} />
}
</>
);
}
const Card = React.memo({card, cardsInPlay, setCardsInPlay}) => {
const onDrag = (moveEvent) => {
setCardsInPlay(
cardsInPlay.map(cardInPlay => {
if (cardInPlay.id === card.id) {
return {
...cardInPlay,
x: moveEvent.clientX,
y: moveEvent.clientY
};
}
return cardInPlay;
}));
};
return (<div onDrag={onDrag} />);
});
解决方案
这取决于您如何传递cardsInPlay
给每个Card
组件。只要您只将所需的信息传递给孩子,状态中的数组是否发生变化都没有关系。
例如:
<Card positionX={cardsInPlay[card.id].x} positionY={cardsInPlay[card.id].y} />
不会导致重新渲染,因为即使父数组发生更改,实例本身也不会获得新的道具。但是,如果您将整个数据传递给每个组件:
<Card cardsInPlay={cardsInPlay} />
它将导致所有人重新渲染,因为每个渲染Card
都会获得一个新的道具,因为没有两个数组,对象在 Javascript 中是相等的。
PS:看到示例代码后编辑
推荐阅读
- r - R Markdown Flexdashboard 顶部的绘图/图形截断
- flutter - 颤振列填充空间
- woocommerce - 首页上的 woocommerce 横幅。如何去除?
- scala - 从 akka.stream.scaladsl.Source 读取第一个字节
- swift - 如何在swiftUI中删除观察者?
- powerbi - 如何在 Power BI 可视化中按照所需顺序对数据进行干净排序?(折线图和堆积柱形图)
- python - 使用表单集时如何使django默认用户
- r - 在将字符变量转换为整数时,有一条消息说:强制转换引入的NAs。如何避免这个错误?
- plugins - 如何在 Neo4j 社区版中使用 Kafka
- python - Discord.py|VoiceChannel编辑