[英]React - how to prevent re-render for child component
当我的hover这个数字时,state selectedItem
会变成这个数字悬停。
但是,从我在控制台中看到的情况来看,每次我 hover 一个数字,所有 7 个项目都会重新渲染,这是我想要避免的情况。
怎么做?
应用程序.js
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [selectedItem, setSelectedItem] = useState(1);
const Item = ({ itemId }) => {
const onItemHover = (id) => {
setSelectedItem(id);
};
console.log("rendering item ", itemId);
return (
<div
onMouseOver={() => {
onItemHover(itemId);
}}
>
{itemId}
</div>
);
};
return (
<div className="App">
<div>Selected ITEM: {selectedItem}</div>
<div className=".container">
<div className="row">
<Item itemId="1" />
<Item itemId="2" />
</div>
<div className="row">
<Item itemId="3" />
<Item itemId="4" />
<Item itemId="5" />
</div>
<div className="row">
<Item itemId="6" />
<Item itemId="7" />
</div>
</div>
</div>
);
}
代码沙盒:
https://codesandbox.io/s/jolly-panini-6gl6b?file=/src/App.js:106-118
将Item
移出组件并对其进行memo
化:
const Item = React.memo({ setSelectedItem, itemId }) => {
const onItemHover = (id) => {
setSelectedItem(id);
};
console.log("rendering item ", itemId);
return (
<div
onMouseOver={() => {
onItemHover(itemId);
}}
>
{itemId}
</div>
);
});
默认情况下, memo
会进行浅层相等性检查,并且在属性未更改时不会重新渲染。
您将setSelectedItem
以及itemId
传递给它:
export default function App() {
const [selectedItem, setSelectedItem] = useState(1);
return (
<div className="App">
<div>Selected ITEM: {selectedItem}</div>
<div className=".container">
<div className="row">
<Item setSelectedItem={setSelectedItem} itemId="1" />
<Item setSelectedItem={setSelectedItem} itemId="2" />
</div>
<div className="row">
<Item setSelectedItem={setSelectedItem} itemId="3" />
<Item setSelectedItem={setSelectedItem} itemId="4" />
<Item setSelectedItem={setSelectedItem} itemId="5" />
</div>
<div className="row">
<Item setSelectedItem={setSelectedItem} itemId="6" />
<Item setSelectedItem={setSelectedItem} itemId="7" />
</div>
</div>
</div>
);
}
useState
state 设置器是稳定的,因此不会因更改而导致重新渲染。 所以Item
只会在itemId
发生变化时重新渲染。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.