Javascript 带挂钩的React:防止使用函数作为道具重新渲染组件
假设我有:Javascript 带挂钩的React:防止使用函数作为道具重新渲染组件,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,假设我有: const AddItemButton = React.memo(({ onClick }) => { // Goal is to make sure this gets printed only once console.error('Button Rendered!'); return <button onClick={onClick}>Add Item</button>; }); const App = () => { co
const AddItemButton = React.memo(({ onClick }) => {
// Goal is to make sure this gets printed only once
console.error('Button Rendered!');
return <button onClick={onClick}>Add Item</button>;
});
const App = () => {
const [items, setItems] = useState([]);
const addItem = () => {
setItems(items.concat(Math.random()));
}
return (
<div>
<AddItemButton onClick={addItem} />
<ul>
{items.map(item => <li key={item}>{item}</li>)}
</ul>
</div>
);
};
但这是重用第一次渲染中的setItems,而
const addItemMemoized = React.memo(() => addItem, [items])
由于项
引用更改,因此不进行记忆
我做不到
const addItem = () => {
items.push(Math.random());
setItems(items);
}
因为这不会改变项的引用,也不会更新任何内容
一种奇怪的方法是:
const [, frobState] = useState();
const addItemMemoized = useMemo(() => () => {
items.push(Math.random());
frobState(Symbol())
}, [items]);
但我想知道是否有更好的方法不需要额外的状态引用 当前首选的路线是,这与您的useMemo
解决方案相同,但将来可能会进行其他优化。传递一个空数组[]
,以确保函数在组件的生命周期内始终具有相同的引用
在这里,您还需要使用,以确保始终基于当前状态添加项目
const addItem = useCallback(() => {
setItems(items => [...items, Math.random()]);
}, []);
“useCallback(fn,inputs)相当于useMemo(()=>fn,inputs)。”这就是我所做的。但是,由于项目引用因spread/concat而发生更改,因此不会被记住。在这里,您可以将[items]
更改为[]
,因为更新取决于以前的状态,所以它仍然可以工作。我将编辑我的答案。我认为这里的关键是在setItems中使用函数!谢谢@kingdaroYep,这样就可以了:P当然可以
const addItem = useCallback(() => {
setItems(items => [...items, Math.random()]);
}, []);