Невозможно обновить компонент при рендеринге другого компонента

Я использую хук useAuth для своего authContext, чтобы я мог использовать хук для установки глобальных состояний для своих компонентов.

Теперь я пытаюсь перейти на страницу '/', если пользователь не вошел в систему, а также отобразить requireLoginAlert пользователю на странице '/' после того, как пользователь был перенаправлен. Однако при попытке включить функцию setRequireLoginAlert(true) в requireAuth.js я получил следующую ошибку.

Warning: Cannot update a component (`AuthProvider`) while rendering a different component (`RequireAuth`). To locate the bad setState() call inside `RequireAuth`

Мой requireAuth.js:

const RequireAuth = () => {
  const { auth, setRequireLoginAlert } = useAuth();
  const location = useLocation();

  return (
    auth?.user 
      ? <Outlet />
      : <Navigate to='/' state={{ from: location }} replace />
      && setRequireLoginAlert(true)
  );
};

export default RequireAuth;

Мой AuthContext.js

const AuthContext = createContext({});

export const AuthProvider = ({ children }) => {
  const [auth, setAuth] = useState({});
  const [requireLoginAlert, setRequireLoginAlert] = useState(false);

  return (
    <AuthContext.Provider value={{ auth, setAuth, requireLoginAlert, setRequireLoginAlert }}>
      {children}
    </AuthContext.Provider>
  );
};

export default AuthContext;

Я пытался использовать useEffect отображение оповещения всякий раз, когда location менялось, но таким образом оповещение будет появляться всякий раз, когда я перехожу на другие страницы, что не идеально. Мне нужен триггер для изменения состояния requireLoginAlert после того, как пользователь был перенаправлен без ошибок.

Не стесняйтесь оставить комментарий, если у вас есть какие-либо идеи. Большое спасибо.

Разве эта ошибка не появляется, потому что вы возвращаете компонент Navigate и вызываете функцию из своего контекста? Возможно, переместите этот вызов в useEffect, а в ответ отобразите только компонент.

szczocik 17.05.2022 16:08

да это точно проблема! Я решил это через useEffect на данный момент

David Ho 17.05.2022 17:07
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
2
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что вы были на правильном пути с подходом useEffect.

Действительно, вы используете местоположение в массиве зависимостей, но вам также необходимо включить условие, основанное на текущей странице, чтобы requireLoginAlert не вызывался каждый раз

Вы пробовали что-то вроде следующего фрагмента кода?

useEffect(
  () => auth?.user && location === "/" && setRequireLoginAlert(true),
  [auth?.user, location]
);

да ты прав. Я создал useEffect следующим образом: `useEffect(() => { if (!auth?.user && location.pathname === '/home/') setRequireLoginAlert(true); }, [auth?.user, location ]);` Работает нормально. Не уверен, что найду ошибку в будущем, так как делаю многостраничный сайт. Спасибо, что поделился!

David Ho 17.05.2022 17:06

Другие вопросы по теме