React Router V4 Recap and Demo

React Router V4 简介

最近很久没有React Router,好像上一次用还在用V3,最近被问了个关于react routerv4的小问题,怎么也想不起来了,决定自己看着文档,再重新demo一遍复习一下。

package

React Router主要包含三个包: react-router, react-router-dom,react-router-nativereact-router包含了主要的route component和功能。react-router-domreact-router-native提供了基于不同平台(web和mobile)的component(类似于react需要把react和react-dom库分开的原因,为了支持不同的平台)。

Note
但是react-router-domreact-router-native中都包含了react-router这个库,因此在项目中使用的时候只需要根据你的平台安装上react-router-dom或者react-router-native即可

The Router

本文基于浏览器做平台。首先你需要确定使用哪一种Router。
React Router中包含两种router(被分装成component)。

区别

  • HashRouter:

    使用URL中的hash部分保持URL和页面内容的同步。

    • 不支持location.key和location.state
  • BrowserRouter:

    URL始终和页面的UI同步

    • 针对于服务器可以server所有URL,并返回不同的页面

每一个Router组件只能接受一个child component,通常会创建一个App Component作为子组件render app剩下的部分。将应用从 router 中分离对服务器端渲染有重要意义,因为我们在服务器端转换到 时可以很快复用 ??????

import { BrowserRouter } from 'react-router-dom'
ReactDOM.render((
  
    
  
), document.getElementById('root'))

History

每一个Router(通常一个SPA会有一个Router)都会创建一个History对象,可以将这个对象理解成一个Location object数组,用来存储浏览器URL的变化轨迹。虽然hostory记录着历史,但是你只能从中get到当前的Location object。

每当地址栏发生改变,history对象就会改变(history存储在react的context),因此Router component的update就开始了。保证了此时页面内容会随着每次URL的改变rerender。

因此Router组件必须是最外层组件。

Location Object

Location object反应的是你当前的地址信息,包含了很多从地址栏中分出的信息

{
  pathname: '/here',
  search: '?key=value',
  hash: '#extra-information',
  state: { modal: true }, //这个是可以attach到这个location上的数据,但是不会出现在URL中
  key: 'abc123' //这个location的唯一标志,也可以理解成数据存放的key
}

Routes

组件是 React Router 的主要组成部分,如果你想要在路径符合的时候在任何地方渲染什么东西,你就应该创造一个 元素。

What does the render?

每一个Route component 都必须有一个属性,能够描述当这个route被match的时候应该render些什么。以下三个属性可以用来描述render的内容。

component

当被match的时候,Route 组件会将会使用React.createElement创建一个component属性指定类型的React component。

render

属性的类型是一个function,这个function可以返回一个component(类似于react render props)。用于当你想要传递一些属性给被render的component的时候使用

上面两个属性必须使用一个
children

也是一个function return 一个component,对于上两个属性,只有route被匹配的时候才会被render。 这个属性,只要写了,不论任何情况这个component都会被render

Path

Route组件需要一个属性path,描述了这个route需要匹配的pathname(仅包含port之后search之前的部分)。比如 能够匹配上的应该是pathname以/roster开头的所有URL,一旦match上相应的component就会被render


// when the pathname is '/', the path does not match
// when the pathname is '/roster' or '/roster/2', the path matches
// If you only want to match '/roster', then you need to use
// the "exact" prop. The following will match '/roster', but not
// '/roster/2'.

// You might find yourself adding the exact prop to most routes.
// In the future (i.e. v5), the exact prop will likely be true by
// default. For more information on that, you can check out this 
// GitHub issue:
// https://github.com/ReactTraining/react-router/issues/4958

Note:

  • react-router只会匹配pathname,也就意味着对于http://www.example.com/my-projects/one?extra=false,在react-router中等价于http://www.example.com/my-projects/one
  • react-router中route的位置,决定了send的URL匹配的是哪一个route。
  • 注意选择是否要加参数exact, 因为不使用exact的时候,只要URL使用path开头就会被匹配

render component props

对于任何一个被匹配的route,这个route被render的component一定能够接受三个属性:

  • location:描述当前的所在的URL

    hash: ""
    pathname: "/"
    search: ""
    state: undefined
    
  • history

    react router的Router创建的history对象,其中包含history API中包含的function,还有当前URL的location对象

  • match

    isExact: true
    params: {}
    path: "/"
    url: "/"
    

match object

当URL和某一个route match上的时候,会立刻创建一个match object

url 被match的URL的pathname
params path params (/a/b/:id中的id就是path params)
path route path属性的值
isExact 是否是exact的完全匹配(path === url)

Note: match的object存储在匹配的component的props中

使用browserRouter请求/roaster总是404

此时我的express是这样配置的:

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.resolve(__dirname,'../','./dist')));

module.exports = app;

也就意味着,当请求/roaster 发送过来文件/dist/roaster一定不存在,所以导致404。

因为单页应用,必须要保证每一个URL发过来都应该返回index.html然后JS文件回来浏览器再处理route问题

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.resolve(__dirname,'../','./dist')));

app.get('*', function (req,res) {
  res.sendFile(path.resolve(__dirname,'../','./dist/index.html'))
});

module.exports = app;

使用browserRouter请求/roaster/id JS file 404

仔细查看生成的HTML文件,发现

你可能感兴趣的:(React Router V4 Recap and Demo)