【问题标题】:Components are not receiving route props组件没有收到路由道具
【发布时间】:2021-05-06 04:25:31
【问题描述】:

文档状态

所有三个渲染方法都将传递相同的三个路由道具 匹配位置记录

他们用这个例子来展示它

import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";

// All route props (match, location and history) are available to User
function User(props) {
  return <h1>Hello {props.match.params.username}!</h1>;
}

ReactDOM.render(
  <Router>
    <Route path="/user/:username" component={User} />
  </Router>,
  node
);

看起来很简单。

但后来我用我的代码尝试了它,但它不起作用。

import * as React from 'react';
import { Switch, Route, BrowserRouter, Redirect } from 'react-router-dom';
import { isFalsy, readFromStorage } from 'utils/general.utils';

import { Homepage } from './pages/homepage/Loadable';
import { Header } from './global/components';
import { Register } from './pages/auth/register/Loadable';
import { Login } from './pages/auth/login/Loadable';
import { ACCESS_TOKEN } from 'constants/storage.constants';

const PrivateRoute = ({ children, ...rest }) => {
  const accessToken = readFromStorage(ACCESS_TOKEN);
  return (
    <Route
      {...rest}
      render={({ location }) =>
        !isFalsy(accessToken) ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: location },
            }}
          />
        )
      }
    />
  );
};

export function App(props) {
  const routes = [
    {
      path: ['/'],
      component: Homepage,
      exact: true,
      private: false,
    },
    {
      path: ['/register'],
      component: Register,
      private: false,
    },
    {
      path: ['/login'],
      component: Login,
      private: false,
    },
  ];

  return (
    <BrowserRouter>
      <Header />
      <Switch>
        {routes.map(route => {
          const Component = route.component;
          const RouteWrapper = route.private ? PrivateRoute : Route;
          return (
            <RouteWrapper
              key={route.path[0]}
              path={route.path}
              exact={route.exact}
            >
              <Component {...props} />
            </RouteWrapper>
          );
        })}
      </Switch>
    </BrowserRouter>
  );
}

是的,我将App 包裹在ReactDom likeso 中

ReactDOM.render(
  <Provider store={store}>
    <HelmetProvider>
      <React.StrictMode>
        <App />
      </React.StrictMode>
    </HelmetProvider>
  </Provider>,
  ROOT,
);

但是RegisterLoginHome组件没有路由的props。我在这里做错了什么?

我正在使用 v5.2.0

【问题讨论】:

    标签: reactjs react-router react-router-dom


    【解决方案1】:

    问题

    您根本没有将路由道具传递给渲染的组件,因为您总是将子组件渲染为包装的子组件,rendercomponent 或@987654327 之一@道具。

    const PrivateRoute = ({ children, ...rest }) => {
      const accessToken = readFromStorage(ACCESS_TOKEN);
      return (
        <Route
          {...rest}
          render={({ location }) =>
            !isFalsy(accessToken) ? (
              children // <-- Just renders children, passes no props
            ) : (
              <Redirect
                to={{
                  pathname: '/login',
                  state: { from: location },
                }}
              />
            )
          }
        />
      );
    };
    

    然后你将传递给 App 的 props 传递出去

    export function App(props) { // <-- props
      const routes = [....];
    
      return (
        <BrowserRouter>
          <Header />
          <Switch>
            {routes.map(route => {
              const Component = route.component;
              const RouteWrapper = route.private ? PrivateRoute : Route;
              return (
                <RouteWrapper
                  key={route.path[0]}
                  path={route.path}
                  exact={route.exact}
                >
                  <Component {...props} /> // <-- spread here, no route props
                </RouteWrapper>
              );
            })}
          </Switch>
        </BrowserRouter>
      );
    }
    

    解决方案

    1. 重写您的 PrivateRoute 组件以呈现 RouteRedirect 以便可以传递路由道具。

      const PrivateRoute = (props) => {
        const accessToken = readFromStorage(ACCESS_TOKEN);
      
        return !isFalsy(accessToken) ? (
          <Route {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: props.location },
            }}
          />
        );
      };
      
    2. 将(几乎)整个路由配置对象传递给包装器。在这里,您将传播pathexactcomponent(或render 等)到RoutePrivateRoute,这将传递路径道具。

      <Switch>
        {routes.map(({ private: isPrivate, ...props }) => {
          const RouteWrapper = isPrivate ? PrivateRoute : Route;
          return (
            <RouteWrapper
              key={props.path[0]}
              {...props}
            />
          );
        })}
      </Switch>
      

    演示

    【讨论】:

    • 太棒了!我明白你现在的意思了。谢谢你和我一起看看德鲁,谢谢!我现在唯一需要做的就是拥有history,将它传递给我的redux-saga,这样我就可以在我的传奇中导航了!! :)
    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 2019-08-15
    • 2021-02-03
    • 2017-06-20
    • 2018-06-28
    • 1970-01-01
    • 2018-12-19
    • 2018-06-03
    相关资源
    最近更新 更多