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

IT技术 javascript reactjs redux react-router
2021-05-09 16:39:39

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

我使用了 ReactTraining 网站的AuthWorkflow示例。在那里,他们使用了一个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;

如何成功将用户对象发送到受保护的组件?

4个回答

您需要将传递给组件...rest参数传递给PrivateRoute组件,但并非所有参数都需要对组件做出react。您可以解构 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 }
          }}
        />
      )
    }
  />
);

看看问题出在哪里:

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

现在在PrivateRoute组件内部,用户对象将作为props传递,它将在rest对象中可用rest,还将包含 所需的数据Route,因此使其更通用。

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

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

将该数据传递给 <Component {...data} {...props} />

带有 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;

没什么特别的,只需调用渲染函数并将一些数据传递给组件即可。

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