Как показать статус входа при перенаправлении на домашнюю страницу

Я использую файлы cookie только http для аутентификации в бэкэнде nodejs, поэтому не могу получить к ним доступ из document.cookies. У меня есть внутренний API для отображения статуса аутентификации. Этот API вызывается в useEffect корневого макета. Когда я загружаю страницу, вызывается API и отображается мое имя пользователя, если у меня есть действительные файлы cookie.

const [userName, setUserName] = useState();
const [userId, setUserId] = useState();

useEffect(() => {
  const showMe = async () => {
    let res = await axios.get(
      "http://localhost:5000/api/v1/users/showMe",
      {
        withCredentials: true,
      }
    );
    console.info("Entered in root useEffect");
    setUserName(res.data.user.name);
    setUserId(res.data.user.userId);
  };
  showMe();
}, [userName, userId]);

Теперь, когда я нажимаю кнопку входа в систему, на сервере выполняется запрос API с соответствующими учетными данными, в результате чего генерируются мои файлы cookie. Я использую действие react-router в пути "/login" для отправки запроса на вход. Если ответ в порядке, я использую redirect, чтобы вернуться на главную страницу.

export const action = async ({ request, params }) => {
  console.info(params);
  const data = await request.formData();
  const loginData = {
    email: data.get("email"),
    password: data.get("password"),
  };

  console.info(loginData);

  let url = "http://localhost:5000/api/v1/auth/login";

  const response = await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(loginData),
    credentials: "include",
  });

  if (response.status === 422) {
    console.info(response);
    return response;
  }

  if (!response.ok) {
    console.info(response);
    throw json({ message: "Could not login." }, { status: 500 });
  }

  return redirect("/");
};

Теперь после перенаправления на домашнюю страницу мой статус входа не обновляется, поскольку ни корневой макет не перезагружается при перенаправлении, ни useEffect внутри него не вызывается. Когда я вручную перезагружаю страницу еще раз, я вижу свой статус входа. Как я могу это исправить, чтобы мне не приходилось делать дополнительную перезагрузку?

Объект маршрутизации

{
  path: "/",
  element: <RootLayout />,
  children: [
    { index: true, element: <Home /> },
    {
      path: "login",
      element: <Login></Login>,
      action: action,
    },
    {
      path: "logout",
      element: <Logout></Logout>,
      action: logoutAction,
    },
  ],
}

Можете ли вы отредактировать , включив в него полный минимальный воспроизводимый пример кода маршрутизации, который отображает маршруты и вызывает загрузчики/действия?

Drew Reese 26.09.2023 07:20

Хорошо, я отредактировал, добавив код маршрутизации.

Shaharin Ahmed 26.09.2023 07:29

Итак, у вас есть useEffect в RootLayout, которые вы хотите активировать снова после входа в систему? Можете ли вы также поделиться маршрутизированными компонентами как частью полного минимально воспроизводимого примера? Вероятно, вы также не хотите, чтобы userName и userId были зависимостями useEffect, поскольку именно это обновляется эффект. Это может привести к зацикливанию рендеринга.

Drew Reese 26.09.2023 07:35
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Похоже, проблема, с которой вы столкнулись, связана с тем, что useEffect в вашем компоненте RootLayout не запускается после успешного перенаправления входа в систему. Это связано с тем, что React Router не выполняет автоматическую повторную визуализацию компонента при изменении маршрута, но компонент уже смонтирован.

Чтобы решить эту проблему и обновить статус входа без перезагрузки страницы вручную, вы можете использовать перехватчик useLocation React Router для обнаружения изменений в маршруте и запуска функции showMe при изменении маршрута. Вот как вы можете это сделать:

import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import axios from 'axios';

function RootLayout() {
  const location = useLocation(); // Get the current route location

  const [userName, setUserName] = useState('');
  const [userId, setUserId] = useState('');

  useEffect(() => {
    const showMe = async () => {
      let res = await axios.get('http://localhost:5000/api/v1/users/showMe', {
        withCredentials: true,
      });
      console.info('Entered in root useEffect');
      setUserName(res.data.user.name);
      setUserId(res.data.user.userId);
    };

    // Call showMe whenever the route changes
    showMe();
  }, [location]); // Add location to the dependency array

  // ... rest of your component code
}

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