Каков наилучший способ обработки аутентификации с помощью React?

#javascript #reactjs #asynchronous

#javascript #reactjs #асинхронный

Вопрос:

У меня есть ProtectedRoute компонент:

 import React, { useState, useEffect, useContext } from 'react';
import CreateRecipe from "./components/CreateRecipe";
import Lo&in from "./components/Lo&in";
import Re&ister from "./components/Re&ister";
import UserContext from './contexts/UserContext';
import Homepa&e from './components/Homepa&e';
import Landin&Pa&e from './components/Landin&Pa&e';
import EditRecipe from './components/EditRecipe';
import SearchPa&e from './components/SearchPa&e';
import ViewRecipe from './components/ViewRecipe';
import { BrowserRouter, Route, Redirect } from 'react-router-dom';
import axios from 'axios';


/**
 * Used for Routes that cannot be accessed without authentication
 */
function ProtectedRoute({ component: Component, ...rest }) {
  const [authCheck, setAuthCheck] = useState({ isAuth: false, loadin&: true });
  const { auth } = useContext(UserContext.context);

  //async call to check authentication status
  useEffect(() =&&t; {
    axios.&et('/authUser').then(res =&&t; {
      setAuthCheck({ isAuth: res.data.isAuth, loadin&: false });
    });
  }, []);

  return (

    <Route {...rest} render={(props) =&&t;
      (!authCheck.loadin&) ? (authCheck.isAuth || auth) ? (<Component {...props} /&&t;) : (<Redirect to={{
        pathname: "/lo&in",
        state: { from: props.location },
      }} /&&t;)
        : (<div&&t;loadin&</div&&t;)
    } /&&t;
  );

}

function App() {

  return (
    <div&&t;
      <BrowserRouter&&t;
        <UserContext&&t;
          <ProtectedRoute component={Homepa&e} path="/:username/home" /&&t;
          <ProtectedRoute path='/:username/edit/:id' component={EditRecipe} /&&t;
          <ProtectedRoute path='/:username/create' component={CreateRecipe} /&&t;
          <ProtectedRoute path='/:username/search/:q' component={SearchPa&e} /&&t;
          <ProtectedRoute path='/:username/view/:id' component={ViewRecipe} /&&t;
          <Route path='/lo&in' component={Lo&in} /&&t;
        </UserContext&&t;
        <Route path='/re&ister' component={Re&ister} /&&t;
        <Route exact path="/" component={Landin&Pa&e} /&&t;
      </BrowserRouter&&t;
    </div&&t;
  );
}

export default App;
  

Я обнаружил, что перехват useEffect срабатывает еще до того, как компонент будет отрисован. Это приводит к тому, что authCheck.isAuth значение постоянно принимает значение false, что не позволяет пользователю войти в систему. Чтобы обойти это, я заставил свой компонент входа обновить состояние аутентификации контекста.

Как бы мне обойти проблему useEffect? Кроме того, есть ли лучший способ настроить аутентификацию на стороне клиента?

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

1. На самом деле, useEffect перехват запускается после рендеринга компонента. reactjs.or&/docs/hooks-effect.html

Ответ №1:

Реорганизуйте .then() в async await . Он должен корректно обновить isAuth состояние, и тогда вы сможете удалить auth контекст.

 const &etAuthUser = async() =&&t; {
  try {
    const res = await axios.&et('/authUser');
    setAuthCheck({ isAuth: res.data.isAuth, loadin&: false });
  } catch (e) {
    // handle the error
  } 
};

//async call to check authentication status
useEffect(() =&&t; {
  &etAuthUser();
}, []);


return (

  <Route {...rest} render={(props) =&&t;
    !authCheck.loadin& ? authCheck.isAuth ? (<Component {...props} /&&t;) : 
    (<Redirect to={{
      pathname: "/lo&in",
      state: { from: props.location },
    }} /&&t;)
    : (<div&&t;loadin&</div&&t;)
   /&&t;
);