В чем смысл обратного вызова по отношению к useAuthProvider?

#javascript #reactjs #dependencies #react-admin

Вопрос:

Я работаю над проектом, в котором useAuthProvider вызывает эффект использования для выполнения рендеринга. Как мне этого избежать?

 const authProvider = useAuthProvider();
const [loading, setLoading] = useState(true);
const [loaded, setLoaded] = useState(false);
const [roles, setRoles] = useState([]);

useEffect(() => {
    authProvider()
      .then((data) => {
        setRoles(data);
        setLoaded(true);
      })
      .catch((err) => {
        console.error(err);
      })
      .finally(() => {
        setLoading(false);
      });
}, [authProvider]);
 

Каждый раз, когда этот крючок запускается, AuthProvider является объектом, поэтому поверхностное сравнение эффекта использования всегда будет оцениваться как ложное.

Я тоже попробовал просто вытащить нужную мне функцию.

 const {getRoles} = useAuthProvider()
 

Однако функция getRoles также всегда будет иметь значение false в зависимостях useEffect, поскольку useAuthProvider создает новый экземпляр функции при каждом рендеринге.

Похоже, это может быть хорошим вариантом использования для обратного вызова. Но мы сталкиваемся с точно такой же проблемой.

 const getRolesCallback = useCallback(
    () => authProvider.getRoles(),
    [authProvider]
  );
 

useCallback имеет точно такую же проверку зависимостей, при которой AuthProvider принимает значение false, и поэтому useCallback обновляет функцию и снова запускает эффект использования.

Я смотрел на некоторые из кода администратора react, где они на самом деле используют useCallback таким образом, но я не вижу, как он что-то делает.

Это из /ra-core/src/auth/useGetPermissions.ts

 const useGetPermissions = (): GetPermissions => {
    const authProvider = useAuthProvider();
    const getPermissions = useCallback(
        (params: any = {}) => authProvider.getPermissions(params),
        [authProvider]
    );

    return authProvider ? getPermissions : getPermissionsWithoutProvider;
};
 

Не будет ли этот обратный вызов бесполезен, потому что зависимость AuthProvider каждый раз будет иметь значение false? Я что-то упускаю?

Спасибо за любую помощь.

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

1. Вы хотите, чтобы он запускался только при запуске?

Ответ №1:

Насколько я вижу, вам вообще не нужно включать authProvider в свои зависимости, [] для вашего варианта использования подойдет просто пустой массив. Пустой массив для параметра зависимости (2-й) означает, что крючок будет просто запущен при первоначальном рендеринге.

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

1. Верно. Я думаю, что просто прочитал слишком много статей, в которых рекомендуется не применять эту практику. Проблема в том, что этот метод просто пытается обмануть react, что нет никаких зависимостей, когда на самом деле они есть. Это может привести к тому, что очень трудно будет отследить ошибки. twitter.com/kentcdodds/status/1141190707232698369?lang=en

2. Хорошая мысль. Что произойдет, если вы используете authProvider.getPermissions в качестве зависимости? Это может указывать на не сгенерированную функцию, которая в любом случае лучше подходила бы для обратного вызова, поскольку это конкретное используемое свойство (метод).

3. Я должен снова проверить эту проблему, так как это было некоторое время назад. Я думаю, что react-admin, возможно, добавил что-то в useAuthProvider, что решает эту проблему, поэтому он не запускает эффект использования каждый цикл. Но мне придется проверить это еще раз.