【问题标题】:Pass custom data to PrivateRoute component in React将自定义数据传递给 React 中的 PrivateRoute 组件
【发布时间】: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;

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

【问题讨论】:

    标签: javascript reactjs redux react-router


    【解决方案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"
      />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-14
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多