react-router

react-router包含三个库:react-router、react-router-dom、react-router-native;react-router提供基本的路由功能,实际使用时不需要直接安装,根据运行环境选择react-router-dom(浏览器中)或react-router-native(rn中)

路由使用例子:

// ReactRouterPage.js
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        <Router>
          <Link to="/">首页</Link>
          <Link to="/user">用户中心</Link>
          <Link to="/login">登录</Link>
          {/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
          {/**path如果不写,则一直匹配 */}
          {/**Switch独占路由 匹配一个 */}
          {/**什么都不写放在最后如404 */}
          <Switch>
            <Route exact path="/" component={HomePage} />
            <Route path="/user" component={UserPage} />
            <Route path="/login" component={LoginPage} />
            <Route render={() => <div>404</div>} />
          </Switch>
        </Router>
      </div>
    );
  }
}

动态路由:使用:id的形式定义动态路由

// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        <Router>
          <Link to="/">首页</Link>
          <Link to="/user">用户中心</Link>
          <Link to="/login">登录</Link>
          <Link to="/search/123">搜索</Link>
          {/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
          {/**path如果不写,则一直匹配 */}
          {/**Switch独占路由 匹配一个 */}
          {/**什么都不写放在最后如404 */}
          <Switch>
            <Route exact path="/" component={HomePage} />
            <Route path="/user" component={UserPage} />
            <Route path="/login" component={LoginPage} />
            {/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
            <Route path="/search/:id" component={SearchComponent} />

            <Route render={() => <div>404</div>} />
          </Switch>
        </Router>
      </div>
    );
  }
}

function SearchComponent(props) {
  console.log(props, "search");
  const { id } = props.match.params;
  return <div>{id}</div>;
}

  

嵌套路由:

嵌套路由:
// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        <Router>
          <Link to="/">首页</Link>
          <Link to="/user">用户中心</Link>
          <Link to="/login">登录</Link>
          <Link to="/search/123">搜索</Link>
          {/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
          {/**path如果不写,则一直匹配 */}
          {/**Switch独占路由 匹配一个 */}
          {/**什么都不写放在最后如404 */}
          <Switch>
            <Route exact path="/" component={HomePage} />
            <Route path="/user" component={UserPage} />
            <Route path="/login" component={LoginPage} />
            {/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
            <Route path="/search/:id" component={SearchComponent} />

            <Route render={() => <div>404</div>} />
          </Switch>
        </Router>
      </div>
    );
  }
}

function DetailComponent(props) {
  return <div>DetailComponent</div>;
}

function SearchComponent(props) {
  console.log(props, "search");
  const { id } = props.match.params;
  return (
    <div>
      searchComponent-{id}
      {/**嵌套路由 */}
      <Link to={"/search/" + id + "/detail"}>详情</Link>
      <Route path={"/search/:" + id + "/detail"} component={DetailComponent} />
    </div>
  );
}

  

路由守卫:

//  src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store/index";

// 把Provider放在根组件外层,使得子组件都能获得store
ReactDOM.render(
  <Provider store={store}>
    <App />,
  </Provider>,
  document.getElementById("root")
);

//  src/App.js
import React from "react";
import RouterPage from "./pages/RouterPage.js";

function App() {
  return (
    <div className="App">
      <RouterPage />
    </div>
  );
}

export default App;

//  store/index.js
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import logger from "redux-logger";

const initalUserInfo = {
  isLogin: false,
  user: { name: null },
};

// 定义修改规则
function countReducer(state = 0, action) {
  switch (action.type) {
    case "ADD":
      return state + 1;
    case "MINUS":
      return state - 1;
    default:
      return state;
  }
}

// 定义修改规则 登录
function loginReducer(state = { ...initalUserInfo }, action) {
  switch (action.type) {
    case "LOGIN_SUCCESS":
      return {
        isLogin: true,
        user: { name: "xss" },
      };
    case "LOGOUT_SUCCESS":
      return {
        isLogin: false,
        user: { name: null },
      };
    default:
      return state;
  }
}

const store = createStore(
  combineReducers({ user: loginReducer }, countReducer),
  applyMiddleware(thunk, logger)
);
export default store;


//  pages/RouterPage.js
// react-router包含3个库,react-router、react-router-dom、react-router-native;
// react-router提供最基本的路由功能,实际使用时不要直接安装react-router,而是根据运行
// 环境选择安装react-router-dom(浏览器中)还是react-router-native(rn中);
// react-router-dom和react-router-native都依赖react-router,所以在安装时,
// react-router也会自动安装,创建web应用

// npm i --save react-router-dom

// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";
import PrivateRoute from "./PrivateRoute";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        <Router>
          <Link to="/">首页</Link>
          <Link to="/user">用户中心</Link>
          <Link to="/login">登录</Link>
          <Link to="/search/123">搜索</Link>
          {/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
          {/**path如果不写,则一直匹配 */}
          {/**Switch独占路由 匹配一个 */}
          {/**什么都不写放在最后如404 */}
          <Switch>
            <Route exact path="/" component={HomePage} />
            {/**路由守卫 */}
            <PrivateRoute path="/user" component={UserPage} />
            {/**<Route path="/user" component={UserPage} />*/}
            <Route path="/login" component={LoginPage} />
            {/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
            <Route path="/search/:id" component={SearchComponent} />

            <Route render={() => <div>404</div>} />
          </Switch>
        </Router>
      </div>
    );
  }
}

function DetailComponent(props) {
  return <div>DetailComponent</div>;
}

function SearchComponent(props) {
  console.log(props, "search");
  const { id } = props.match.params;
  return (
    <div>
      searchComponent-{id}
      {/**嵌套路由 */}
      <Link to={"/search/" + id + "/detail"}>详情</Link>
      <Route path={"/search/:" + id + "/detail"} component={DetailComponent} />
    </div>
  );
}

// pages/PrivateRoute.js
import React, { Component } from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";

export default connect(({ user }) => ({ isLogin: user.isLogin }))(
  class PrivateRoute extends Component {
    render() {
      const { isLogin, path, component } = this.props;
      if (isLogin) {
        return <Route path={path} component={component} />;
      } else {
        return (
          <Redirect
            to={{
              pathname: "/login",
              state: {
                redirect: path,
              },
            }}
          />
        );
      }
    }
  }
);

// pages/LoginPage.js
import React, { Component } from "react";
import { Redirect } from "react-router-dom";
import { connect } from "react-redux";

export default connect(
  // mapStateToProps
  ({ user }) => ({ isLogin: user.isLogin }),
  // mapDispatchToProps
  {
    login: () => ({ type: "LOGIN_SUCCESS" }),
  }
)(
  class LoginPage extends Component {
    render() {
      const { isLogin, login, location } = this.props;
      // 如果已经登录,则跳回之前PrivateRoute.js存储的页面路径state中的redirect
      // 如果直接输入路由login而不是从PrivateRoute页面进来会报错,要给个默认值
      const { redirect = "/" } = location.state || {};
      if (isLogin) {
        return <Redirect to={redirect} />;
      } else {
        return (
          <div>
            <h3>LoginPage</h3>
            <button onClick={login}>login</button>
          </div>
        );
      }
    }
  }
);


// pages/UserPage.js
import React, { Component } from "react";
import { connect } from "react-redux";

export default connect(({ user }) => ({ isLogin: user.isLogin }), {
  logout: () => ({ type: "LOGOUT_SUCCESS" }),
})(
  class UserPage extends Component {
    render() {
      const { logout } = this.props;
      return (
        <div>
          UserPage
          <button onClick={logout}>logout</button>
        </div>
      );
    }
  }
);

// pages/HomePage.js
import React, { Component } from "react";
import "./HomePage.less";
export default class HomePage extends Component {
  render() {
    return (
      <div className="homepage">
        <h3>HomePage</h3>
      </div>
    );
  }
}

  

  

Route渲染内容的三种方式及其优先级:children》component》render 

 ps:感谢 & 参考 各路大神

原文地址:https://www.cnblogs.com/haimengqingyuan/p/13406457.html