react嵌套路由以及exact属性用法

时间:2024-04-01 15:24:22

序言

关于react的路由,与结合vue-router对比,实际上配置更复杂,虽然有各种轻量级框架对react-router进行封装,单还需了解基本原理,废话不多说,上代码

路由

我这里采用es6的写法,与官文相比,使用有状态的react组件实现嵌套路由,首先搭建好环境,我这里利用create-react-app脚手架工具,不知道的同学请看参考文档,搭建好的项目结构如下

react嵌套路由以及exact属性用法
引入react-router,有cnpm和yarn命令可替换下图

npm i react-router-dom --save

将server运行起来后,将src/App.js文件修改如下

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Router>
        <div>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/topics">Topics</Link>
            </li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
        </div>
        </Router>
      </div>
    );
  }
}

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}

class Topics extends Component {
  componentDidMount() {
    console.log(this);
  }
  render() {
    const { match } = this.props;
    return (
      <div>
        <h2>Topics</h2>
        <ul>
          <li>
            <Link to={`${match.url}/rendering`}>Rendering with React</Link>
          </li>
          <li>
            <Link to={`${match.url}/components`}>Components</Link>
          </li>
          <li>
            <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
          </li>
        </ul>

        <Route path={`${match.path}/:topicId`} component={Topic} />
        <Route
          exact
          path={match.path}
          render={() => <h3>Please select a topic.</h3>}
        />
      </div>
    )
  }
}

class Topic extends Component {
  render() {
    const { match } = this.props;
    return (
      <div>
        <h3>{match.params.topicId}</h3>
      </div>
    );
  }
}

export default App;

这里重点说下从react-router-dom引入的Route附件,Route的位置代表了所对应的component显示的位置,这一点很重要

Topics 所对应的路由组件下又进行了Route的设置,并且在子组件Topic的路由配置中拿到父组件的相对路径match.url,这种写法有利于路由组件的维护,即使改变了层级,子路由的path也不用改变,需要注意当时组件是否有传入路由参数。

exact 属性

关于Route的exact,加上exact代表当前路由path的路径采用精确匹配,比如说Home的path如果不加上exact,那么path="/about"将会匹配他自己与path="/“这两个,所以一般path=”/"这个路由一般会加上exact,另外需要注意一点的是嵌套路由不要加exact属性,如果父级路由加上,这里例如topics加上该属性,他下面的子路由将不会生效,因为外层强制匹配了。

react-router总体来讲配置还是挺复杂的,需要提前构思好整个路由如何搭建,望诸君多多尝试,上诉代码已上传至gitHub有兴趣可下载自行尝试