将自定义数据传递给 React 中的 PrivateRoute 组件

Posted

技术标签:

【中文标题】将自定义数据传递给 React 中的 PrivateRoute 组件【英文标题】:Pass custom data to PrivateRoute component in React 【发布时间】:2018-08-09 04:31:13 【问题描述】:

我是 ReactJS 的新手,我用 React 开始了我的第一个应用程序。我一直在观看视频并阅读各种教程,最后设法用 Login 搭建了我的第一个 ReactRedux 应用程序。

我使用了AuthWorkflow ReactTraining 网站的示例。他们在那里使用PrivateRoute 组件来保护受保护的路由。我已经实现了它并且它的工作原理。

问题: 现在我无法将任何自定义数据或类似用户数据发送到受保护的路线。如何发送?

代码

import React from "react";
import 
  BrowserRouter as Router,
  Route,
  Link,
  Redirect,
  withRouter
 from "react-router-dom";

////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time

const AuthExample = () => (
  <Router>
    <div>
      <AuthButton />
      <ul>
        <li>
          <Link to="/public">Public Page</Link>
        </li>
        <li>
          <Link to="/protected">Protected Page</Link>
        </li>
      </ul>
      <Route path="/public" component=Public />
      <Route path="/login" component=Login />

       // Here I want to pass the user data to protected component.
      <PrivateRoute path="/protected" component=Protected user=username:'ariful', email:'test@example.com'/>
    </div>
  </Router>
);

const fakeAuth = 
  isAuthenticated: false,
  authenticate(cb) 
    this.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  ,
  signout(cb) 
    this.isAuthenticated = false;
    setTimeout(cb, 100);
  
;

const AuthButton = withRouter(
  ( history ) =>
    fakeAuth.isAuthenticated ? (
      <p>
        Welcome!" "
        <button
          onClick=() => 
            fakeAuth.signout(() => history.push("/"));
          
        >
          Sign out
        </button>
      </p>
    ) : (
      <p>You are not logged in.</p>
    )
);

const PrivateRoute = ( component: Component, ...rest ) => (
  <Route
    ...rest
    render=props =>
      fakeAuth.isAuthenticated ? (
        <Component ...props />
      ) : (
        <Redirect
          to=
            pathname: "/login",
            state:  from: props.location 
          
        />
      )
    
  />
);

const Public = () => <h3>Public</h3>;

// show the username here
const Protected = (props) => <h3>Protected Username: props.user.username</h3>;

class Login extends React.Component 
  state = 
    redirectToReferrer: false
  ;

  login = () => 
    fakeAuth.authenticate(() => 
      this.setState( redirectToReferrer: true );
    );
  ;

  render() 
    const  from  = this.props.location.state ||  from:  pathname: "/"  ;
    const  redirectToReferrer  = this.state;

    if (redirectToReferrer) 
      return <Redirect to=from />;
    

    return (
      <div>
        <p>You must log in to view the page at from.pathname</p>
        <button onClick=this.login>Log in</button>
      </div>
    );
  


export default AuthExample;

我怎样才能成功地将用户对象发送到受保护的组件?

【问题讨论】:

【参考方案1】:

您需要将传递给PrivateRoute...rest 参数传递给组件,但并非所有这些参数都需要对组件做出反应。您可以解构 React 路由器所需的其他参数

const PrivateRoute = ( component: Component, exact, strict, path, ...rest ) => (
  <Route
    exact=exact
    strict=strict
    path=path
    render=props =>
      fakeAuth.isAuthenticated ? (
        <Component ...props ...rest />
      ) : (
        <Redirect
          to=
            pathname: "/login",
            state:  from: props.location 
          
        />
      )
    
  />
);

【讨论】:

谢谢。完美运行。 @ArifulHaque,很高兴能帮上忙,这确实是一个很好的问题【参考方案2】:

看看问题出在哪里:

<PrivateRoute 
   path="/protected" 
   component=Protected 
   user=username:'ariful', email:'test@example.com' />

现在在PrivateRoute 组件中,用户对象将作为道具传递,它将在rest 对象中可用,rest 也将拥有Route 所需的数据,所以让它更多通用的。

而不是传递用户对象总是传递data,现在rest将有Route所需的数据,数据将是传递给组件的数据,这样写:

const PrivateRoute = ( component: Component, data, ...rest ) => (
  <Route
    ...rest
    render=props =>
      fakeAuth.isAuthenticated ? (
        <Component ...props ...data />
      ) : (
        <Redirect
          to=
            pathname: "/login",
            state:  from: props.location 
          
        />
      )
    
  />
);

将该数据传递给&lt;Component ...data ...props /&gt;

【讨论】:

支持解释。也会尝试这种方法。【参考方案3】:

带有 react-redux 钩子的功能组件的 PrivateRoute

import React from 'react';
import  Route, Redirect  from 'react-router-dom';
import useSelector from 'react-redux'

const PrivateRoute = ( component: Component, auth, ...rest ) => 
const isAuthenticated = useSelector((state)=>state.isAuthenticated)
  return (
    <Route
    ...rest
render=props =>
  isAuthenticated === true ? (
    <Component ...props />
  ) : (
    <Redirect to="/login" />
  )

/>
)



export default PrivateRoute;

【讨论】:

【参考方案4】:

没什么花哨的,只是调用一个渲染函数并将一些数据传递给组件。

<PrivateRoute
 render = () => 
  <Component
   data = value
  />
 path = "/path"
/>

【讨论】:

以上是关于将自定义数据传递给 React 中的 PrivateRoute 组件的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 将自定义数据传递给电子邮件视图

如何将 ajax 数据传递给 React 组件?

React:将传入的服务数据传递给孩子

将数据传递给 Windows 控制台控制处理程序

将数据传递给服务器显示未定义

如何将设计数据传递给React组件?