Есть ли способ определить хук в for?

#javascript #reactjs #react-hooks #reducers

#javascript #reactjs #реагирующие перехваты #редукторы

Вопрос:

Для еще большей оптимизации / общей логики я хочу создать useSelectors продукт, который использует многократный обратный вызов.

Здесь useSeletors нужно включить селекторы (как в redux) useReducer . Итак, это мой код :

 const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => 
        (...args) => (selector(state, ...args))
    ), 
    [state]
);
 

Что я хотел сделать, так это :

 const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => useCallback(
        (...args) => (selector(state, ...args))), 
        [state]
    ), 
    [state]
);
 

Что на самом деле вызывает ошибку.
Вероятно, я смогу это сделать :

 const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => selector(state)), 
    [state]
);
 

Но я теряю возможность использовать аргументы для моей функции выбора.
Может быть, это не проблема, потому что есть кое-что, чего я пока не понимаю, о useCallback :
Если я использую a useCallback без указания аргументов, но с указанием зависимости, это будет почти как переменная.
Выполняется ли он при первом вызове? В следующий раз (без обновления зависимости) я напрямую получаю возврат функции без выполнения?

Итак, что произойдет, если я добавлю переменные аргументы (например, счетчик) в обратный вызов?
вероятно, он повторно выполнит функцию с этим новым аргументом, даже если зависимость не изменится?
Так что useCallback , структура стала бесполезной с аргументами?

Последний момент, который я хочу спросить: когда выполняется обратный вызов?
Для a useMemo функция выполняется в первый раз при объявлении is ? (Или в первый раз, когда мы используем его переменную? => Разница в данном случае не очень важна.)
Did useCallback вызывается в первый раз только тогда, когда он вызывается с () помощью в коде или при его объявлении?
Пример :

 const myVar = useMemo(() => 5 5, [dependency]); // executed
const myFunc = useCallback(() => 5 5, [dependency]);

myVar; // 10
myFunc(); // executed => 10

myVar; // 10
myFunc(); // 10
 

Так что, если это работает так, лучше вызвать useCallBack useMemo , чтобы выполнить селектор только тогда, когда он вызывается, а не при монтировании в моем третьем решении.
Это основная причина, по которой я хочу использовать multiple useCallbacks в своем перехвате, не зная номера.

[ПРАВИТЬ / ПРАВИТЬ код]

Второе предложение с useCallback не имеет смысла, потому что :

 const test = useCallback(() => {
        console.log('test is executed');
        return 'test';
    }, [state]);
    console.log(test());
    console.log(test());
 

Журналы :

тест выполняется
тест
выполняется тест выполняется
тест

И не то, что я ожидал :

тест выполняется
тестовый
тест

Так что он не может быть лучше, чем первый

Ответ №1:

useCallback возвращает функцию. Когда одна из зависимостей этого перехвата (например, некоторый счетчик) изменяется useCallback , вызывается снова и возвращает новую функцию. Это происходит потому, что переданная функция useCallback не знает, что счетчик изменен, пока useCallback не выполнит его повторно.

useMemo работает так же, но возвращает значение. Теоретически вы можете реализовать useCallback использование useMemo , возвращая функцию вместо значения. Я имею useCallback(fn, deps) в виду то же useMemo(() => fn, deps) самое, что и .

Вы можете прочитать больше об этом в документах React .

В вашем коде вы должны использовать useMemo и не использовать useCallback inside useMemo , потому что вы получите ошибку, и это не лишнее, потому что оно используется при передаче обратных вызовов оптимизированным дочерним компонентам, которые полагаются на равенство ссылок для предотвращения ненужного рендеринга. Это не ваш случай. Ваш первый пример кода правильный.

Комментарии:

1. Я уже прочитал документ, но я, вероятно, переоценил useCallback