Реагировать перехватом useCallback для рендеринга карты
При передаче обратного вызова компоненту, я должен использовать useCallback
ловушка для возврата запомненного обратного вызова (для предотвращения ненужных рендеров):
import doSomething from "./doSomething";
const FrequentlyRerenders = ({ id }) => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent onEvent={ onEvent } />
);
};
Но что, если я использую карту? например:
import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent key={id} onEvent={ onEvent } />
);
});
};
Как правильно использовать useCallback
? Вышеуказанный правильный способ передать несколько обратных вызовов? Это действительно работает и знает, чтобы запоминать каждый обратный вызов в соответствии с элементом массива?
3 ответа
Преобразуйте возвращенный сопоставленный JSX в компонент, и тогда вы сможете без проблем использовать Обратный вызов
import doSomething from "./doSomething";
const MappedComponent =(props) => {
const onEvent = useCallback(() => doSomething(props.id), []);
return (
<ExpensiveComponent onEvent={ onEvent } />
);
}
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
return <MappedComponent key={id} id={id} />
});
};
Теперь это прямо не рекомендуется в документации.https://reactjs.org/docs/hooks-rules.html
Старый ответ
Ответ на повторный архитектор - уклонение от вопроса ИМО. Хотя я думаю, что создание нового компонента, вероятно, хорошая идея.
Чтобы ответить на вопрос, ваш код:
import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent key={id} onEvent={ onEvent } />
);
});
};
На самом деле это то, что вы хотели бы сделать, чтобы запоминать на карте. Я не знаю реализации useCallback, но она должна добавить очень мало накладных расходов на память. StackFrame и все, что они делают, чтобы уменьшить массив до некоего ключа для мемоизированной функции.
Если вы не работаете над некоторыми с ТОННОЙ элементов, EG реагирует на виртуальные компоненты с неограниченной прокруткой, вы действительно можете безопасно использовать Callback таким, какой вы есть. Фактически, небольшие накладные расходы на память, вероятно, намного дешевле, чем повторный рендеринг всех этих компонентов.
Еще одна альтернатива:
import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
const onEvent = useCallback((id) => () => doSomething(id), []);
return ids.map(id => {
return (
<ExpensiveComponent key={id} onEvent={ onEvent: onEvent(id) } />
);
});
};