Защищенные маршруты для маршрутизатора react v5 не работают

#reactjs #routes #react-router #react-router-dom #protected

Вопрос:

Я пытаюсь создать защищенный/закрытый маршрут с помощью react-router-dom v5, как в ссылке здесь, я использую только необходимый мне код — Защищенные маршруты и аутентификацию с помощью React Router v5.
Теперь мне нужны оба компонента, закрытые друг от друга
Проблема: после переноса Home компонента из SignUp компонентов я могу вернуться SignUp , и это не то, что я хочу.

Регистрация в настоящее время является первой страницей (как вход в систему). Я не хочу, чтобы пользователь возвращался к компонентам вздоха, если он уже зарегистрировался и присутствует в Home компоненте.

Проект рабочего сайта находится здесь — CodeSandbox

У кого-нибудь есть идея, как я могу сделать оба компонента защищенными/закрытыми?

Охраняемый маршрут.jsx

 function GuardedRoute({ children, auth, ...rest }) {
  return (
    <Route
      {...rest}
      render={() => {
        return auth === true ? children : <Redirect to="/signup" />;
      }}
    />
  );
}

export default GuardedRoute;
 

App.js

 const App = () => {
  const [userID, setUserID] = useState('');
  const [userSignedUp, setIfSignUp] = useState(false);
  return (
    <div className="App-div">
      <GuardedRoute exact path="/home" auth={userSignedUp}>
        <Home userIDNumber={userID} setIfSignUp={setIfSignUp} />
      </GuardedRoute>
      <Switch>
        <Route path="/signup">
          <SignUp setUserNumber={setUserID} setIfSignUp={setIfSignUp} />
        </Route>
      </Switch>
    </div>
  );
};

export default App;
 

Пожалуйста, попробуйте любое из ваших решений в моем codesandbox, прежде чем публиковать свой ответ, чтобы мы не пробовали решения только в теории и напрасно 🙂

Ответ №1:

Вы можете сделать signup так, чтобы маршрут существовал только в том случае, если пользователь не вошел в систему, а затем использовать уловку, которая перенаправит на /home

 <div className="App-div">
  <Switch>
    {!userSignedUp amp;amp; (
      <Route path="/signup">
        <SignUp setUserNumber={setUserID} setIfSignUp={setIfSignUp} />
      </Route>
    )}
    <GuardedRoute path="/home" auth={userSignedUp}>
      <Home userIDNumber={userID} setIfSignUp={setIfSignUp} />
    </GuardedRoute>

    <Route path="/">
      <Redirect to="/home" />
    </Route>
  </Switch>
</div>
 

Обновленный образец: https://codesandbox.io/s/jolly-https-t7dmj?file=/src/containers/App.js


или вы могли бы инкапсулировать логику в другой компонент , например GuardedRoute , скажем UnguardedRoute , который перенаправит куда-нибудь, если пользователь вошел в систему.

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

1. Хорошо, Габриэле тай, зачем это <Route path="/"> <Redirect to="/home" /> </Route> нужно ? Почему это не сработает без него ? это похоже на дублированный код.

2. У меня есть UnguardedRoute почти такой же, как у GuardedRoute меня, но все равно без <Route path="/"><Redirect to="/home" /></Route> я получаю только http://localhost:3002/ пустой экран.

3. Я пытаюсь понять, если я нахожусь SignUp и стираю URL — адрес таким образом- localhost:3002 , он не будет Home отображаться . Это почему? Как это работает ? Спасибо, Габриэле, что уделил мне время и объяснил.

4. Если вы находитесь на localhost:3002 , то ни один из маршрутов path , которые у вас есть, не соответствует. Так что ничего не будет оказано. path="/" Маршрут, который я добавил в конце, будет соответствовать чему угодно. И поскольку все они находятся в коммутаторе, поэтому может совпадать только один — в порядке сверху вниз, когда path совпадение отсутствует, он достигнет того, который перенаправляет.

5. Я не пользуюсь этим {!userSignedUp amp;amp; ( условием. Когда userSignedUp === fasle, я задался вопросом, как он будет проверять, GuardedRoute если он сначала отправится Redirect to ='/home' . Я предпочитаю UnguardedRoute то же GuardedRoute самое, что и .