我是 Hooks的新手,并尝试使用 Hooks 创建一个 PureComponent 等效版本。 我的目标是创建一个多选列表,其中包含一个负责呈现列表项的子组件:
const Movie: FunctionComponent<{
title: string,
score: number,
id: number,
isSelected: boolean,
setSelected: React.Dispatch<React.SetStateAction<{}>>
}> = React.memo(({ title, score, isSelected, setSelected, id }) => {
const selectMovie = (): void => {
if (isSelected === null)
return;
setSelected(id);
};
const selected = {
backgroundColor: "blue"
}
console.log("render movie")
return (
<div onClick={selectMovie} style={isSelected ? selected : {}}>
{title}, {score}
</div>
)
})
父组件具有数据以及选择的逻辑:
const App: FunctionComponent = () => {
const data = [
{
id: 1,
title: "Pulp fiction",
score: 9
},
{
id: 2,
title: "Heat",
score: 8
},
{
id: 3,
title: "American pie",
score: 7
}
]
const [selectedItems, setSelected] = React.useState<{}>({});
const selectMovie = React.useCallback((id: any) => {
const sel: any = {...selectedItems};
if (sel.hasOwnProperty(id)) {
delete sel[id]
} else {
sel[id] = true;
}
setSelected(sel);
}, [selectedItems])
return (
<div>
{
data.map(e => <Movie key={e.id} {...e} setSelected={selectMovie} isSelected={selectedItems.hasOwnProperty(e.id)}/>)
}
</div>
)
}
我做了一个沙盒,你可以在那里尝试一下:https://codesandbox.io/s/old-sun-38n4u
选择状态在对象的父组件中维护,并作为布尔值提供给子组件。问题是当我单击电影时,所有 3 个列表项都会重新渲染(您可以在控制台中看到日志(。我也使用了React.memo
和useCallback
来避免为道具比较重新创建箭头函数。我对钩子很陌生,所以它一定是我忽略了一些愚蠢的事情......
这是因为由于 selectedItems 依赖项更改,您的 selectMovie 每次都会更改。
setSelected 函数也可以接受一个函数,您可以获取 selectedItems 值,因此无需将其设置为依赖项
这是工作沙盒