Условный маршрут, не отображающий перенаправленный макет

#reactjs #react-router #react-router-v4

#reactjs #реагировать-маршрутизатор #react-router-v4

Вопрос:

В AppRouter у меня есть условный маршрут с перенаправлением для <AdminLayout/> .

соответствующий фрагмент:

 <Route
          exact
          path="/admin"
          strict
          render={(props) => <AdminLayout {...props} />}
        >
          {loggedIn ? <Redirect to="/admin/summary" /> : <Login />}
        </Route>
  

Если loggedIn значение true, тогда перенаправьте на /admin/summary , иначе перенаправьте его обратно на <Login/>

Проблема в том, что он только изменяет URL, но не отображает <AdminLayout/> .

Не уверен, где я ошибаюсь и чего мне не хватает.

ОБНОВЛЕНЫ PrivateRoute и AppRouter ниже

AppRouter

 import React, { useEffect } from "react";
import { Router, Route, Switch, Redirect } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { createBrowserHistory } from "history";

import { alertActions } from "../actions";
import { history } from "../helpers";

import AdminLayout from "layouts/Admin/Admin.js";
import AuthLayout from "layouts/Auth/Auth.js";
import ResetPassword from "../components/pages/reset-password/ResetPassword";
import MailReset from "../components/pages/reset-password/MailReset";
import PrivateRoute from "../routes/PrivateRoute";
import Dashboard from "views/Dashboard";

const hist = createBrowserHistory();

const AppRouter = () => {
  const alert = useSelector((state) => state.alert);
  const dispatch = useDispatch();

  useEffect(() => {
    history.listen((location, action) => {
      // clear alert on location change
      dispatch(alertActions.clear());
    });
  }, []);

  return (
    <Router history={hist}>
      <Switch>
        {/* <Route path="/admin" render={(props) => <AdminLayout {...props} />} /> */}
        <PrivateRoute exact path="/admin">
          <Dashboard />
        </PrivateRoute>
        <Route
          path="/auth/login"
          render={(props) => <AuthLayout {...props} />}
        />
        <Route exact path="/auth/forgotPassword" component={ResetPassword} />
        <Route exact path="/auth/mail_reset" component={MailReset} />
        <Redirect from="*" to="/auth/login" />
      </Switch>
    </Router>
  );
};

export default AppRouter;
  

PrivateRoute

 import React from "react";
import { Route, Redirect } from "react-router-dom";

import AdminLayout from "../layouts/Admin/Admin";

function PrivateRoute({ component: Component, roles, ...rest }) {
  console.log("rest pvt route", ...rest);
  return (
    <Route
      {...rest}
      render={(props) => {
        console.log("propsssss", props);
        // if (!localStorage.getItem('userid')) {
        if (!localStorage.getItem("access_token")) {
          // not logged in so redirect to login page with the return url
          return (
            <Redirect
              to={{ pathname: "/auth/login", state: { from: props.location } }}
            />
          );
        }

        // logged in so return component
        return <AdminLayout {...props} />;
      }}
    />
  );
}

export default { PrivateRoute };
  

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

1. Это потому, что вы используете оба render и children одновременно. Этот пример поможет вам добавить AuthRoutes . Если все еще не понимает, дайте мне знать, тогда добавится песочница.

2. спасибо за пример. Я написал PrivateRoute компонент, но не смог заставить его работать. Итак, затем я попробовал это. Не могли бы вы, пожалуйста, изолировать его. Я также обновил описание своим PrivateRoute компонентом, на случай, если это пригодится.

Ответ №1:

Итак, пытаюсь объяснить, что это неправильно:

  1. Вы настраиваете рендеринг, child и render props поэтому children здесь приоритет имеет props:
 <Route
          exact
          path="/admin"
          render={(props) => <AdminLayout {...props} />}
        >
          {loggedIn ? <Redirect to="/admin/summary" /> : <Login />}
        </Route>
  
  1. Ваш частный маршрут правильный, но также необходимо добавить свой макет:
 return <AdminLayout {...props} /><Component {...props} /></AdminLayout/>;
  
  1. Внутри маршрута приложения вам нужно импортировать PrivateRoute компонент, он будет выглядеть следующим образом:
 import PrivateRoute from './PrivateRoute';

const AppRouter = () => {
  const alert = useSelector((state) => state.alert);
  const loggedIn = useSelector((state) => state.authentication.loggedIn);

  const dispatch = useDispatch();

  useEffect(() => {
    history.listen((location, action) => {
      // clear alert on location change
      dispatch(alertActions.clear());
    });
  }, []);

  return (
    <Router history={hist}>
      <Switch>
        <PrivateRoute exact path='/admin'>
          <YOUR AUTH COMPONENT WHICH YOU WANT TO RENDER />
        </PrivateRoute>
        <Route
          path='/auth/login'
          render={(props) => <AuthLayout {...props} />}
        />
        <Route exact path='/auth/forgotPassword' component={ResetPassword} />
        <Route exact path='/auth/mail_reset' component={MailReset} />
        <Redirect from='*' to='/auth/login' />
      </Switch>
    </Router>
  );
};

        
  

Здесь я создал демонстрационный код этого. Возьмите из него ссылку:https://codesandbox.io/s/react-router-redirects-auth-forked-6q6o4?file=/example.js

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

1. спасибо за изолированную среду. Я попытался реализовать ваши предложения. Но не смог заставить его работать. Попробовал ваш # 2, даже обернув его вокруг фрагмента, все еще безуспешно. Я обновил свое описание после того, как попробовал ваши предложения.

2. в чем проблема? Можете ли вы, пожалуйста, добавить песочницу. Это может быть какая-то незначительная ошибка. Что трудно прочитать из этого кода. И песочница помогают другому разработчику быстро устранить проблему

3. Просто создайте минимальный пример того, что вы пытаетесь сделать. Вам не нужно устанавливать какие-либо другие дополнительные библиотеки redux

4. да, верно. Я сделаю это. Проблема в том, что он изменяет URL, но сначала он не загружает компонент, а затем, когда я обновляю страницу, он загружает пробел с /admin/summary URL.

5. Вы экспортируете PrivateRoute неправильно, поэтому он выдает ошибку. Добавлена и обновлена ваша изолированная среда. Вот демонстрация: codesandbox.io/s/floral-fire-szql3?file=/src/Dashboard.js