Допустим, у меня есть:
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>
);
};
Каждый раз, когда я добавляю элемент, <AddItemButton />
перерисовывается, потому что addItem - новый экземпляр.Я пытался запоминать addItem:
const addItemMemoized = React.memo(() => addItem, [setItems])
Но это повторное использование setItems с первого рендеринга, в то время как
const addItemMemoized = React.memo(() => addItem, [items])
Не запоминает, поскольку items
изменение ссылки.
Я могу сделать
const addItem = () => {
items.push(Math.random());
setItems(items);
}
Так как это не меняет ссылку на items
и ничего не обновляется.
Один странный способ сделать это:
const [, frobState] = useState();
const addItemMemoized = useMemo(() => () => {
items.push(Math.random());
frobState(Symbol())
}, [items]);
Но мне интересно, есть ли лучший способ, который не требует дополнительных ссылок на состояние.