在带有私有路由的react-router dom 中使用渲染

IT技术 reactjs react-router react-router-v4
2021-04-30 08:17:28

我尝试使用 react router dom v4 在私有路由中渲染两个组件。使用普通 Route 可以做到这一点,但使用自定义 Route 时似乎并非如此。我收到以下错误:“警告:React.createElement:类型无效——需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义。您可能忘记导出您的组件来自它定义的文件,或者您可能混淆了默认导入和命名导入。”

自定义路由(已认证)
return (
      <Route
        {...rest}
        render={props =>
          this.currentUser()
            ? <Component currentUser={this.currentUser} {...props} />
            : <Redirect
                to={{
                  pathname: '/auth/login',
                  state: { from: props.location }
                }}
              />
        }
      />
    )
然后在我的路线中,我想要这样的东西
return (
      <div>
        <Switch location={isModal ? this.prevLocation : location}>
          <Authenticated path="/" exact component={Main} />
          <Route path="/auth/register" exact component={Register} />
          <Route path="/auth/login" exact component={Login} />
          <Authenticated
            path="/clients/:id/edit"
            render={(props) => ( // Not working as expected. Works fine using Route instead of Authenticated
              <div>
                <Main />   
                <ClientEdit />
              </div>
            )}
          />
        </Switch>
        {isModal ?
          <Authenticated
            path='/clients/new'
            component={ClientNew}
          />
        : null}
        {isModal ?
          <Authenticated
            path='/clients/:id/edit'
            component={ClientEdit}
          />
        : null}
      </div>
    );
4个回答

我有点晚了,但是对于仍然需要它的人,我发现这对我有用。

export function PrivateRoute({ component: Component = null, render: Render = null, ...rest }) {
  const authService = new AuthService();

  return (
    <Route
      {...rest}
      render={props =>
        authService.isAuthenticated ? (
          Render ? (
            Render(props)
          ) : Component ? (
            <Component {...props} />
          ) : null
        ) : (
          <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )
      }
    />
  );
}

在我的路线中,我像这样使用它:

<PrivateRoute
    path="/some-route/edit"
    render={props => <MyComponent {...props} isAwesome={true} />} />

在您的 protectedRoute 组件中,您没有接收或使用render您在行中发送的props:

render={(props) => ( 
  <div>
    <Main />   
    <ClientEdit />
  </div>
)}

而不是使用渲染发送componentprop 中的组件,如:

component={(props) => ( 
  <div>
    <Main />   
    <ClientEdit />
  </div>
)}

还可以查看 react router 的文档以了解何时使用componentprop 以及何时使用renderprop。如果你能改变你protectedRoute的处理方式会更好

我认为您需要创建一个自定义组件返回:

return(
  <div>
   <Main />   
   <ClientEdit />
  </div>)

然后导入它并在您的认证组件中使用它,如下所示:

<Authenticated
   path="/clients/:id/edit"
   component={CustomComponent}
 />

编辑:如果提供,您还可以在 Authenticated 组件中处理渲染props:

if (this.props.render && this.currentUser()) {
  return(
    <Route
      {...rest}
      render={this.props.render}
    />
} else {
    return (
       <Route
         {...rest}
         render={props => this.currentUser() ?
            <Component currentUser={this.currentUser} {...props} /> : 
            <Redirect
                to={{
                  pathname: '/auth/login',
                  state: { from: props.location }
                }}
             />
          }
        />
      )
}
import React from 'react';
import { Route, Redirect } from "react-router-dom";
const PeivateRoute = ({ component: component, ...rest }) => {
  return (
     <Route
        {...rest}
        render = {props => (false ? <component {...props}/> : <Redirect to="/" />)}
         />
);

};

导出默认 PeivateRoute;