上节课我们初步学习了如何来使用路由,但是也都是一下基本应用,那么这节课我们来对比一下路由组件与一般组件。

回顾

在开始这节课的内容之前,我们来对上节课的内容来做一个简单的回顾。

  • 安装react-router-dom
  • 路由技术分两步
  • 修改浏览器地址栏路径
  • 路由器监听路径映射对应组件
  • react-router中路由器分为BrowserRouterHashRouter
  • 使用路由的话,react-router中的组件都要由路由器管理
  • 整个应用的路由都要用同一个路由器管理
  • 当前最新版的注册路由方法已经改了<Route path="" element={<Component />}>
  • 当前最新版本的SwitchRoutes代替了,当注册路由时必须要交由Routes管理

以上便是上节课要注意的点,尤其最后两条。那么接下来我们来开始这节课的内容。

路由的基本使用

  • 明确导航区与展示区
  • <a>替换为<Link>
  • 注册路由要与路径进行匹配
  • 我们将App组件交给一个路由器管理

路由技术的细节

我们之前已经知道如区使用路由技术了,虽然这都还只是冰山一角,但是我们最最基本的使用已经有了初步了解了。那么我们来说一个细节性的问题吧。

我们知道<a>在代码中要换成<Link>,那么浏览器认识<Link>吗?最终是不是还是要转成<a>啊?但是最后的这个<a>是什么样子呢?我们来看一下页面元素:

image-20220113152759814

好像没有什么区别对不对?就是吧href属性改了。但是实际上在后台程序中是有对应的监听来完成我们的路由流程的。

第二一点,我们用得路由器是BrowserRouter,我们说了还有一个叫HashRouter,那么我们换成HashRouter再来看一下页面会怎么样:

image-20220113153229857

刚一打开页面的时候我们没有匹配任何路径,所以展示区什么也没有,当我们点击一下导航中的任何一个:

image-20220113153342484

页面可以跳转,但是在地址栏,我们的HOST后面多了一个#,这个是啥呢?这个就是就是HashRouter的一个特有的了,#后面的就我们所谓的hash值,或许大家不太明白,大家可以简单理解为锚点值,但是这个说法不严谨,只是为了方便大家理解,面试的时候可别直接蹦出来一句,这个就是锚点值啊,这个特点呢就是#后面的任何数据都不会作为资源发送给服务器的。

组件分类

其实我们在写代码的过程中之前好像一直也没有提过这个问题,但是现在学到了路由,我们得说一下了,我们看这个案例中是不是有Home组件和About组件啊?那么组件是不是都放在components文件夹里面啊?但是这种做饭不规范。因为到了现在组件已经开始有分类了。

就我们所说的路由组件和一般组件。为什么说HomeAbout组件直接放在components中不规范呢?因为这两个组件都是路由组件。

那么什么是路由组件?我们来回头看一下App组件中的代码,我们虽然引入了这两个组件但是我们有直接渲染组件吗?是不是没有,我们是把这两个组件标签传给了注册路由的标签。因为这两个组件是由路由来管理的,所以我们把这两个组件归为路由组件。

那么什么是一般组件呢?可想而知我们把由路由管理的组件归为路由组件,那么直接渲染,不被路由管理的不就是一般组件嘛。

其实在我们实际开发中这些路由组件我们可就不能放在components文件夹离了,而是要放在pages文件夹中。

当然了,其实一般组件和路由组件最大的区别并不是有没有被路由管理。上节课我们因为用得是最新版的react-router-dom,那么我们换成旧一点的版本,方便我们来更详细地介绍我们的内容。

react-router-dom 5.x版本中,我们的代码是这样:

export default class App extends Component {
  render() {
    return (
      <div>
        ...
              <Link className="list-group-item" to="/about">About</Link>
              <Link className="list-group-item" to="/home">Home</Link>
        ...
                <Route path="/about" component={About} />
                <Route path="/home" component={Home} />
        ...
      </div>
    );
  }
}

我们把暂时不需要关注的代码先隐藏掉,我们先来思考一个问题,我们在先组件标签来渲染组件的时候是不是可以传props?而且我们传什么,组件就会收到什么。我们来看一下我们这两个组件是不是并没有被我们手动渲染?那么这里的组件我们是不是根本不能传props?那么他们的props里面是不是就啥都没有呢?那我打印一下不就知道了嘛。

export default class Home extends Component {
  render() {
    console.log(this.props);
    return (
      <h3>我是Home的内容</h3>
    );
  }
}

我们在Home组件中打印一下props

image-20220113160654417

诶?我们获取到了这么些个东西?这些东西都是哪来的呢?这些其实是路由器在渲染我们组件的时候传进来的。当然这些东西我们先不说,后面会慢慢地探讨。所以说这才是一般组件和路由组件最大的区别。

总结

  • 一般组件与路由组件的写法不同
  • 一般组件:<Demo />
  • 路由组件:<Route path="/demo" component={Demo}>注意,这是旧版本的写法
  • 一般组件与路由组件存放位置不同
  • 一般组件与路由组件接收到的props不同
  • 一般组件:写组件标签时传了什么,就能接收到什么
  • 路由组件:无法手动传递,取决于路由器传递,会收到 3 个固定属性。这也是旧版本

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/router_component_and_common_component/