我是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
来避免重新创建箭头函数以进行道具比较。我对钩子还很陌生,所以它一定有点愚蠢,我忽略了……
答案 0 :(得分:1)
这是因为由于selectedItems依赖项的更改,您的selectMovie每次都在更改。
setSelected函数也可以使用一个函数,并且可以获取selectedItems值,因此无需将其设置为依赖项