Мне интересно, как лучше вернуть запомненную функцию обратного вызова в React при использовании фабрики для генерации этого обратного вызова. Цель состоит в том, чтобы вернуть тот же экземпляр функции, когда фабрика вызывается с тем же параметром.
Например:
function MyComponent() {
// This will always return a new function
const makeCallback = param => () => {
/* perform action with 'param' */
};
return (
<>
<Button onClick={makeCallback('foo')} />
<Button onClick={makeCallback('bar')} />
<Button onClick={makeCallback('baz')} />
</>
);
Я не верю, что обертывание самой фабрики с помощью useCallback предоставить какую-либо выгоду, так как эта функция фактически не передается ни одному из дочерних элементов, поэтому я хотел вернуть функцию useCallback с фабрики.
Например:
const makeCallback = param => React.useCallback(
() => {
/* perform action with 'param' */
},
[param]
);
Однако , это было недопустимо и не удалось во время сборки.
React Hook "React.useCallback" is called in function "makeCallback" which is neither a React function component or a custom React Hook function - react-hooks/rules-of-hooks
"Правила хуков" ясно говорят, что вызов хука во вложенной функции не является разрешено, но мне это кажется странным, поскольку пользовательский хук часто буквально является функцией, вызывающей другие хуки. В нем говорится, что основной задачей является сохранение порядка выполнения, но я не думаю, что это будет нарушено в этом случае.
Мой лучший вариант - превратить мою фабрику в ловушку и явно вызвать ее сверху уровень для каждого случая? Я бы предпочел простоту построения обратного вызова в самой кнопке, так как она немного меньше печатает, а часть параметра более очевидна и очевидна, если удерживать ее нажатой.
// Same factory function, but now it's magically a "hook"
const useCallbackFactory = param => {
return React.useCallback(() => { /* do 'param' stuff */ }, [param]);
}
function MyComponent() {
// Define the callbacks ahead of time
const fooCb = useCallbackFactory('foo');
const barCb = useCallbackFactory('bar');
const bazCb = useCallbackFactory('baz');
return (
<>
<Button onClick={fooCb} />
<Button onClick={barCb} />
<Button onClick={bazCb} />
</>
);
}