React-Router示例,重定向与withRouter

1.withRouter作用:把不是通过路由切换过来的组件中,将react-router 的 history、location、match 三个对象传入props对象上

默认情况下必须是经过路由匹配渲染的组件才存在this.props,才拥有路由参数,才能使用编程式导航的写法,执行this.props.history.push('/detail')跳转到对应路由的页面

然而不是所有组件都直接与路由相连(通过路由跳转到此组件)的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,此时就可以使用this.props

2.Redirect渲染<Redirect>将导航到新位置。新位置将覆盖历史堆栈中的当前位置

- to: object

要重定向到的位置。

`
<Redirect to={{
pathname: '/login',
search: '?utm=your+face',
state: { referrer: currentLocation }
}}/>


- push: bool

当为true时,重定向会将新条目推入历史记录,而不是替换当前条目。

`

<Redirect push to="/somewhere/else"/>



- from: string

要重定向的路径名。这只能用于在<Switch>内部呈现<Redirect>时匹配位置。
有关详细信息,请参阅<Switch children>。https://reacttraining.com/web/api/Switch/children-node


`

<Switch>
<Redirect from='/old-path' to='/new-path'/>
<Route path='/new-path' component={Place}/>
</Switch>
import React, { Component } 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

function AuthExample() {
  return (
    <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} />
        <PrivateRoute path="/protected" component={Protected} />
      </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(
  /*withRouter作用:把不是通过路由切换过来的组件中,将react-router 的 history、location、match 三个对象传入props对象上*/
  ({ history,location,match }) =>{
    // console.log(history);    
    // console.log(location);
    // console.log(match);

    return fakeAuth.isAuthenticated ? (//已登录认证就显示下面的组件
      <p>
        Welcome!{" "}
        <button
          onClick={() => {//退出按钮
            fakeAuth.signout(() => history.push("/"));
          }}
        >
          Sign out
        </button>
      </p>
    ) : (//没有登录显示下面的组件
      <p>You are not logged in.</p>
    )    
  }
);

/*重定向路由组件,返回的是一个Route路由*/
function PrivateRoute({ component: Component, ...rest }) {
  return (
    <Route
      {...rest}
      render={props =>
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (//没有登录就显示下面的路由匹配到登录组件
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

/*公共页面无需登录就能访问*/
function Public() {
  return <h3>Public</h3>;
}

/*登录之后访问的组件*/
function Protected() {
  return <h3>Protected</h3>;
}

/*登录组件*/
class Login extends Component {
  state = { redirectToReferrer: false };//重定向状态

  login = () => {//登录方法
    fakeAuth.authenticate(() => {
      this.setState({ redirectToReferrer: true });//登录进行重定向
    });
  };

  render() {
    let { from } = this.props.location.state || { from: { pathname: "/" } };
    let { redirectToReferrer } = this.state;
    console.log(from);//Object {pathname: "/protected", search: "", hash: "", state: undefined, key: "0hr10n"}
    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;

转载自https://reacttraining.com/react-router/web/example/auth-workflow

https://edu.51cto.com/lecturer/11857712.html 星星课堂web前端系列课程

https://edu.51cto.com/course/25959.html js设计模式课程

https://edu.51cto.com/course/23133.html js进阶与组件化实战课程

https://edu.51cto.com/course/24757.html jquery课程

https://edu.51cto.com/course/22392.html js基础与入门课程

https://edu.51cto.com/course/26063.html vue零基础入门课程

https://edu.51cto.com/course/22393.html xhtml与css基础入门课程