繁体   English   中英

页面未呈现; 在 react-router-dom 中使用受保护的路由将道具传递给孩子时

[英]Page not rendering; When passing props to children using protected routes in react-router-dom

我正在尝试使用 react-router-dom 创建受保护的路由。

奇怪的是错误说:

元素类型无效:需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:object。

检查Context.Consumer的渲染方法。

这就是堆栈跟踪——奇怪的是期待字符串的错误? 我不是在history.push中传递"/profile"吗?

外

我说这很奇怪的原因是因为在开发工具的控制台中我得到了这个:

index.js:1 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <Connect(withRouter(LinkNavWithLayout)) />. Did you accidentally export a JSX literal instead of a component?
    in Route (created by PrivateRoute)
    in PrivateRoute (created by App)
    in Switch (created by App)
    in App (created by Context.Consumer)
    in withRouter(App) (created by Connect(withRouter(App)))
    in Connect(withRouter(App)) (created by MyApp)
    in Container (created by MyApp)
    in PersistGate (created by MyApp)
    in Provider (created by MyApp)
    in MyApp (created by AppWithReactRouter)
    in Router (created by BrowserRouter)
    in BrowserRouter (created by AppWithReactRouter)
    in AppWithReactRouter (created by AppWithRedux)
    in AppWithRedux
    in Suspense (created by AppContainer)
    in Container (created by AppContainer)
    in AppContainer

对我来说这更有意义,因为我觉得问题出在受保护的路由组件中,即意味着我的受保护路由 function 中的逻辑或我使用它的方式......

  const PrivateRoute = ({ component: Component, children, ...rest }) => (
   <Route {...rest} render={props => {
    console.log("In PrivateRoute isLoggedIn ", isLoggedIn);
    return isLoggedIn === true
    ? <Component {...props} >{children}</Component>
    : <Redirect to='/' />
   }} />
  )

这就是我使用它的方式。

return (
    <>
    <Switch>
     <Route
      path='/'
      exact
      render={(props) => <LinkNavWithLayout {...props} data={navBars}><Index {...props} /></LinkNavWithLayout>} />

     <Route
      path='/login'
      render={(props) => <Login {...props} />}
     />

     <Route
      path='/register'
      render={(props) => <Register {...props} />}
     />

     <PrivateRoute
      path='/profile'
      isLoggedIn={isLoggedIn}
      component={
       <LinkNavWithLayout data={navBars}><Profile /></LinkNavWithLayout>
      }
     />

     <PrivateRoute
      path='/dashboard'
      isLoggedIn={isLoggedIn}
      component={
       <LinkNavWithLayout data={navBars}><Dashboard /></LinkNavWithLayout>
      }
     />
     {/* <Route component={()=> <h1>Not found</h1>} /> */}
    </Switch>
    </>
  )
 }

那么为什么我的页面根本没有呈现,这两个错误有什么关系呢? 任何帮助将不胜感激!

更新

我添加了fosso的建议...

const PrivateRoute = ({ component, isLoggedIn, ...rest }) => (
   <Route {...rest} render={props => {
    console.log("In PrivateRoute isLoggedIn ", isLoggedIn);
    return isLoggedIn === true
     ? { component }
     : <Redirect to='/' />
   }} />
  )

  return (
    <>
    <Switch>
     <Route
      path='/'
      exact
      render={(props) => <LinkNavWithLayout {...props} data={navBars}><Index {...props} /></LinkNavWithLayout>} />

     <Route
      path='/login'
      render={(props) => <Login {...props} />}
     />

     <Route
      path='/register'
      render={(props) => <Register {...props} />}
     />

     <PrivateRoute
      path='/profile'
      isLoggedIn={isLoggedIn}
      component={({ children }) => ( // not sure where you're planning on passing `children` from `PrivateRoute`
       <LinkNavWithLayout data={navBars}><Profile /></LinkNavWithLayout>
      )}
     />

     <PrivateRoute
      path='/dashboard'
      isLoggedIn={isLoggedIn}
      component={({children}) => ( // not sure where you're planning on passing `children` from `PrivateRoute`
       <LinkNavWithLayout data={navBars}><Dashboard /></LinkNavWithLayout>
      )}
   />
     {/* <Route component={()=> <h1>Not found</h1>} /> */}
    </Switch>
    </>
  )
 }
}

但是现在出现以下错误:

Objects are not valid as a React child (found: object with keys {component}). If you meant to render a collection of children, use an array instead.
    in Route (created by PrivateRoute)
    in PrivateRoute (created by App)
    in Switch (created by App)
    in App (created by Context.Consumer)
    in withRouter(App) (created by Connect(withRouter(App)))
    in Connect(withRouter(App)) (created by MyApp)
    in Container (created by MyApp)
    in PersistGate (created by MyApp)
    in Provider (created by MyApp)
    in MyApp (created by AppWithReactRouter)
    in Router (created by BrowserRouter)
    in BrowserRouter (created by AppWithReactRouter)
    in AppWithReactRouter (created by AppWithRedux)
    in AppWithRedux
    in Suspense (created by AppContainer)
    in Container (created by AppContainer)
    in AppContainer
▶ 30 stack frames were collapsed.
callback

并且仍然指向...

在此处输入图像描述

我看到几个问题。

component必须是 function,在您的情况下,您正在传递一个 React 元素。

在您的情况下,这可能有效:

<PrivateRoute
   path='/dashboard'
   isLoggedIn={isLoggedIn}
   component={({children}) => ( // not sure where you're planning on passing `children` from `PrivateRoute`
    <LinkNavWithLayout data={navBars}><Dashboard /></LinkNavWithLayout>
   )}
/>

作为替代方案,您必须更改PrivateRoute组件

const PrivateRoute = ({ component, isLoggedIn, ...rest }) => (
 <Route {...rest} render={props => {
  console.log("In PrivateRoute isLoggedIn ", isLoggedIn);
  return isLoggedIn === true
  ? {component}
  : <Redirect to='/' />
 }} />
  )

但是你真的应该把它作为一个单独的组件。

在第二个示例中,您将从父级实例化 JSX,这可能并不理想。 在第一种情况下,每次重新渲染时都会生成component ,这可能不是必需的。

编辑:完整示例

const {
  HashRouter,
  Switch,
  Route,
  Link
} = ReactRouterDOM

const Page2 = () => (
  <div>
    <h1>Page2</h1>
  </div>
)

const Page1 = () => (
  <div>
    <h1>Page1</h1>
  </div>
)

const Home = () => (
  <div>
    <h1>Home</h1>
  </div>
)

const PrivateRoute = ({component: Component, isLoggedIn, ...rest}) => (<Route {...rest} render={props => isLoggedIn ? <Component /> : <div>Not logged in</div>} />)

const Content = () => (
  <main>
    <Switch>
      <Route exact path='/' component={Home}/>
      <PrivateRoute path='/page1' isLoggedIn component={Page1}/>
      <PrivateRoute path='/page2' isLoggedIn={false} component={Page2}/>
    </Switch>
  </main>
)

const Nav = () => (
  <header>
    <nav>
      <ul>
        <li><Link to='/'>Home</Link></li>
        <li><Link to='/page1'>Page 1 (logged in)</Link></li>
        <li><Link to='/page2'>Page 2 (not logged in)</Link></li>
      </ul>
    </nav>
  </header>
)

const App = () => (
  <div>
    <Nav />
    <Content />
  </div>
)

ReactDOM.render((
  <HashRouter>
    <App />
  </HashRouter>
), document.getElementById('root'))

在代码笔中测试。 抱歉,但如果还有更多错误,我认为我没有足够的信息来进一步调试。 我建议发布另一个带有完整示例的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM