【问题标题】:Passing props to PrivateRoute Component将 props 传递给 PrivateRoute 组件
【发布时间】:2020-11-01 19:37:18
【问题描述】:

您好,我有一个 react (GatsbyJs) 应用程序,我在其中使用动态获取的数据和身份验证。我有一个 PrivateRoute 组件,它检查用户是否已登录,然后根据状态重定向到组件或登录页面。 我现在需要将 props 传递给组件,但无法掌握它。

这里是 PrivateRouter:

import React from 'react'
import { navigate } from 'gatsby'
import { isLoggedIn } from '../services/auth'

const PrivateRoute = ({ component: Component, location, ...rest }) => {
  if (!isLoggedIn() && location.pathname !== '/app/login') {
    navigate('/app/login')
    return null
  }
  return <Component {...rest} />
}

export default PrivateRoute

还有 app.js 代码:

import React from "react"
import { Router } from "@reach/router"
import Layout from "../components/layout"
import OrderDetails from "../modules/order-details"
import ItemDetails from "../modules/item-details"
import ProductionOrders from "../modules/production-orders"
import ProdOrderDetail from "../modules/production-order-detail"
import CardDetail from '../modules/card-details'
import Cards from "../modules/cards"
import Orders from "../modules/orders"
import Items from "../modules/items"
import PrivateRoute from '../components/privateRoute'
import Profile from '../components/profile'
import Login from '../modules/login'
import ForgotPassword from "../modules/forgotPassword"
import NewPassword from "../modules/newPassword"
import Invoices from "../modules/invoices"
import Dispatches from "../modules/dispatches"
import InvoiceDetails from "../modules/invoice-details"
import OrderPlan from "../modules/order-plan"
import AccountStatementPage from "../modules/acc-statement"




const App = () => {

  return (
    <Layout>
      <Router basepath="/app">
        <PrivateRoute path="/order-details/:orderId" component={OrderDetails} />
        <PrivateRoute path="/item-details/:itemId" component={ItemDetails} />
        <PrivateRoute path='/production-orders' component={ProductionOrders} />
        <PrivateRoute path="/production-order-detail/:companyNr/:orderId" component={ProdOrderDetail} />
        <PrivateRoute path="/cards" component={Cards} />
        <PrivateRoute path="/card-details/:cardId" component={CardDetail} />
        <PrivateRoute path="/orders" component={Orders} />
        <PrivateRoute path="orders/cId/:cId" component={Orders} />
        <PrivateRoute path="orders/keyword/:keyword" component={Orders} />
        <PrivateRoute path="/items" component={Items} />
        <PrivateRoute path="/items/keyword/:keyword" component={Items} />
        <Login path="/login" />
        <ForgotPassword path="/forgot-password" />
        <NewPassword path="/new-password" />
        <PrivateRoute path="/profile" component={Profile} />
        <PrivateRoute path="/invoices/" component={Invoices}/>
        <PrivateRoute path="/invoices/cId/:cId" component={Invoices}/>
        <PrivateRoute path="/dispatches/" component={Dispatches}/>
        <PrivateRoute path="/dispatches/cId/:cId" component={Dispatches}/>
        <PrivateRoute path="/invoice-details/:invId" component={InvoiceDetails} />
        <PrivateRoute path="/order-plan" component={OrderPlan} />
        <PrivateRoute path="/acc-statement/:id" component={AccountStatementPage}/>
      </Router>
    </Layout>
  )
}
export default App

我应该如何修改它们以便能够将道具传递给组件?

提前致谢。

附言

这是组件:

import React from 'react'
import Container from "react-bootstrap/Container"
import Col from 'react-bootstrap/Col'
import Row from 'react-bootstrap/Row'
import AccStatement from '../components/accStatement'



const AccountStatementPage = (props,{location}) => {
console.log(location)
console.log(props)

    return (

        <Container fluid>
            <h1>Cari Hesap Ekstresi</h1>
            <Row className="h-100">
                
            
                        <AccStatement id={props.id} />
               
                
            </Row>
        </Container>
    )
}
export default AccountStatementPage

【问题讨论】:

  • 当您传播rest 时,您已经将传递给PrivateRoute 的所有其他道具传递给呈现的组件。我没有在您的 Router 中看到您传递任何其他道具的地方。你在向PrivateRoute 组件传递什么/在哪里传递额外的道具?
  • 我想像这样在 组件上传递道具:
  • 我明白了。您可以更新您的问题以包含此相关代码吗?您在什么地方以及在哪里呈现链接并尝试将其他数据传递给目标路由?

标签: reactjs gatsby


【解决方案1】:

您的私有路由组件已配置为传递 任何 由路由器传递给它的其他道具 ,但是由于您正尝试向渲染的组件发送其他数据您需要正确发送路由状态。

Link

<Link to=“...” myState=“....” >

您可以通过传递给每个渲染组件的 location 属性访问路由状态。

const MyComponent = ({ location }) => {
  return (
    <div>My route state: {location.state.myState}</div>
  );
};

如果您的组件没有收到路由道具,那么您可以使用useLocation react 钩子。

const MyComponent = () => {
  const location = useLocation();

  return (
    <div>My route state: {location.state.myState}</div>
  );
};

我应该如何在目标组件中访问它?

location 应该被注入到由Route 传递给您的组件的props 对象中。这不是一个单独的论点。路由参数也放在 match 属性上,不是根级别的属性值。

给定

<PrivateRoute
  path="/acc-statement/:id"
  component={AccountStatementPage}
/>

组件

const AccountStatementPage = ({ location, match }) => {
  useEffect(() => {
    // Log route state and match param `id` on mount
    console.log(location.state, match.id);
  }, []);

  return (
    <Container fluid>
      <h1>Cari Hesap Ekstresi</h1>
      <Row className="h-100">
        <AccStatement id={match.id} />
      </Row>
    </Container>
  )
};

【讨论】:

  • 我从组件中获取未定义的位置。我这样调用组件:/app/acc-statement/${card.id}} state={{custName:card.name, custCode:card.code}}>跨度>
  • @Ergun 听起来你的组件没有直接通过路由渲染,或者没有从Route 接收到location 属性。您可以使用 useLocation react 钩子进入路由状态。我已经更新了我的答案。
  • 是的,它是通过另一个调用渲染器组件的组件渲染的。按照我描述的方式做会有问题吗?
  • @Ergun 据我所知,AccountStatementPage 是由包装您的应用程序的 Router 呈现的,因此 location 属性 应该 起作用。您的链接是否呈现到不同的路由器中?您能否更新您的问题,说明您的链接在何处以及如何呈现?
  • 我只有一个 PrivateRoute 组件。 Link 组件是标准的 Gatsbyjs 组件。我没有其他路由器。我有用于身份验证的放大身份验证包装器,这就是原因吗?
【解决方案2】:

在您的PrivateRoute 组件中,您将component 解构为Component(以渲染它)、location,其余的(...rest)用于props 的其余部分。

要将自定义道具传递给PrivateRoute 中的组件,您只需直接访问您的prop

在你的app.js

    <PrivateRoute path="/order-plan" component={OrderPlan} customProp={`hello`}/>

您的customProp 正在通过PrivateRoute 中的rest 扩展运算符传递给您的组件,因此,在您的组件中,只需访问props.customProp

如果你想使用Link组件传递一些东西,你应该使用Gatsby Link本身提供的状态(因为Gatsby是从@reach/router扩展而来的):

<Link
  to={`/order-plan`}
  state={{ yourVariable: 'hello' }}
>

然后,在您的order-plan 页面上,您必须访问props.location.state.yourVariable 才能获取您的数据。

【讨论】:

  • 谢谢。我怎样才能从 传递它?我可以只写
  • rest 不是道具(即没有命名道具rest),它是一个变量包含传递给的道具的“其余部分” PrivateRoute,散布到渲染组件中。
  • 你是完全正确的@DrewReese。我已经用使用Link时的方法更新了答案@user1305579@
  • 不幸的是它不起作用。尝试从组件访问位置时,我变得不确定。
【解决方案3】:

我无法通过位置访问路线状态。它一直是未定义的。 但我可以通过以下方式访问路由状态:

window.history.state.customProps

感谢您的支持,一切安好。

【讨论】:

    【解决方案4】:

    你真的很亲密。

    这对我有用。根据 Gatsby 规范,在 Link 中传递您的状态对象。然后,您需要访问您的 Router 道具(其中包含具有您的 Link 状态的 location 对象)并将 location.state.example 传递给这样的组件。

    链接

    <Link
            className="link-wrapper"
            to={endpoint}
            state={{ example: 'something' }}
          >
    

    RouterPage (PrivateRouter)

    const RouterPage = (
      props: { pageComponent: JSX.Element } & RouteComponentProps
    ): JSX.Element => {
      if (!loggedIn) {
          navigate('/404')
        }
    
      return props.pageComponent
    }
    

    路由器

    const App: React.FC<RouteComponentProps> = (props: any) => {
      return (
          <Router className="below-header-container">
            <RouterPage
              path={withPrefix('/some-path/create')}
              pageComponent={<CreateSomething />}
            />
            <RouterPage
              path={withPrefix('/some-path/:id')}
              pageComponent={
                <EditSomething name={props.location.state.example} />
              }
            />
            <RouterPage
              path={withPrefix('/some-path')}
              pageComponent={<Something />}
            />
          </Router>
      )
    }
    

    组件

    const EditSomething: React.FC<any> = ({ name }) => {
    
      return (
        <section className="edit-something">
          <div className="row">
            <h1>{name}</h1>
          </div>
        </section>
      )
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-09
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 2017-11-17
      • 2019-05-18
      相关资源
      最近更新 更多