Django+React全栈开发:路由
react-router
现在的网站一般来讲很少只有单个“页面”,对于我们的博客来说,除了文章列表的界面,起码还得得有个文章详情页才行。
单页应用(SPA):可能你在官方介绍create-react-app
这个脚手架时已经看到了这个名词,但千万不要误以为单页面的意思是没有“可以点击的链接”的。在这里所说的单页应用实际上就是:既然我们将一个网页应用看作一堆组件的组合,那么动态的页面其实只需要动态更新显示部分组件就行,而不是像传统做法那样,服务端提供完整的新页面,所有资源都重新加载。
好了,看到这里你应该明白,create-react-app
是一个适于构建单页应用的脚手架,但不意味着想要做一个文章详情页就要再次yarn create react-app
新建一个项目了吧。
好了,说了这么多,开始写代码吧。这里我们需要学习一个新东西:react-router-dom
。首先进入我们的frontend
目录,终端运行yarn add react-router-dom
来安装依赖。
函数组件
之前我们已经讲过了类组件,在React
中我们也可以创建函数形式的组件,函数组件又称为无状态组件,它可以接收一个props
作为参数,但是不可以使用state
,它没有状态,也没有生命周期函数(在本教程介绍React Hooks
之前这句话是正确的)。
为了介绍函数组件,这里先拆分一下组件,从ArticleList
拆出一个ArticleItem
。
函数组件顾名思义就是一个函数,只要它返回一个JSX元素,就可以被当作组件使用,这里使用了箭头函数,要了解这些基础知识的细节,推荐去看MDN
、阮一峰的ES6入门教程或者现代JavaScript教程。
ArticleItem
组件的内容是从ArticleList
复制过来的,那么现在去修改ArticleList
的内容:
我们将aritcleList
中的元素当作ArticleItem
的props
传递下去。可以看到这里的ArticleItem
组件就是一个函数,它的返回值就是要渲染的内容。我个人的习惯是有组件需要复用了或者组件太大了再去提取组件,这里纯粹为了演示下函数组件写法。
路由
在开始写代码之前,让我们先来构思一下路由划分:
- 首页,展示文章列表
- 详情页,显示文章详情
- about页,展示博主信息
也就是说我们需要做三个页面,通常网站都会有个导航栏,一般来说进入这三个页面中的任意一个,导航栏都不会消失,也就是导航栏是可以复用的,而页面的主体部分,则可以动态替换。这样我们就知道,需要以下几个组件:
- App组件,主体框架
- 导航栏组件
- 文章列表组件
- 文章详情组件
- About组件
首先改写App.js
:
同时还要新建Nav.js
和About.js
:
别忘了在之前的index.js
中我们渲染的是ArticleList
,现在去更改它:
主要看App
和Nav
两个组件,首先引入了react-router-dom
中BrowserRouter
包裹其它元素,Link
组件放在Nav中做导航链接,Switch
和Route
搭配使用,Switch
会搜索子元素Route
,当找到其路径与当前url
相匹配的Route
时,则渲染此Route
内容,并忽略其它的Route
。例如当前url
为根路径/
,那么就会渲染这里最后一个Route
中的ArticleList
,这样我们点击不同的Link,Switch组件渲染的内容就会切换,达到换页面的目的。如果按F12打开查看元素,你会发现点击不同导航链接,App组件内的元素会切换,而NetWork
中则显示并没有发送任何网络请求。
详情页
现在还剩最后一个页面需要完成,就是文章详情页。现在去修改ArticleList.js
,让其根据文章ID创建不同的Link
:
我们使用ES6
语法的模板字符串,注意<Link to={...}>
里的不是单引号,而是键盘左上角esc键下面那个反引号。这和Python
中的f
字符串有些类似,都允许在字符串中嵌入变量,但是ES6
的写起来有点麻烦。JSX
的实现也离不开模板字符串哦。
OK,现在让我们在src
目录下新建一个ArticleDetail.js
:
对应的,在App.js
中添加一个匹配项:
现在在网页上点击文章标题或者导航栏的链接试试看吧。
练习
现在我们的文章详情组件只是简单地显示了article + id
,可以尝试重写组件以显示真正的文章详情。之前说过函数组件又叫无状态组件,没有state
,也没有生命周期,这里暂时先不讲Hooks
(其实我们已经不知不觉中使用过了),所以你可能要将ArticleDetail
改写为类组件,并通过props
传递文章id
并在componentDidMount
中请求API。