路由
如果要在单页应用中完成组件的切换,需要实现下面两个功能:
- 根据不同的页面地址,展示不同的组件(核心);
- 完成无刷新的地址切换;
我们把实现了以上两个功能的插件,称之为路由
React Router
- react-router:路由核心库,包含诸多和路由功能相关的核心代码;
- react-router-dom:利用路由核心库,结合实际的页面,实现跟页面路由密切相关的功能;
两种模式
Hash Router 哈希路由
根据url地址中的哈希值来确定显示的组件
原因:hash的变化,不会导致页面刷新 这种模式的兼容性最好
Borswer History Router 浏览器历史记录路由
HTML5出现后,新增了History Api,从此以后,浏览器拥有了改变路径而不刷新页面的方式 History表示浏览器的历史记录,它使用栈的方式存储, history表示当前路由的信息。
- history.length:获取栈中数据量
- history.pushState:向当前历史记录栈中加入一条新的记录
- 参数1:附加的数据,自定义的数据,可以是任何类型
- 参数2:页面标题,目前大部分浏览器不支持
- 参数3:新的地址
- history.replaceState:将当前指针指向的历史记录,替换为某个记录
- 参数1:附加的数据,自定义的数据,可以是任何类型
- 参数2:页面标题,目前大部分浏览器不支持
- 参数3:新的地址
路由组件
Router组件
它本身不做任何展示,仅提供路由模式配置,另外,该组件会产生一个上下文,上下文中会提供一些实用的对象和方法,供其他相关组件使用
- HashRouter:该组件,使用hash模式匹配
- BrowserRouter:该组件,使用BrowserHistory模式匹配
通常情况下,Router组件只有一个,将该组件包裹整个页面
Route组件
根据不同的地址,展示不同的组件。 Route组件可以写到任意的地方,只要保证它是Router组件的后代元素
重要属性:
- path:匹配的路径
- 默认情况下,不区分大小写,可以设置sensitive属性为true,来区分大小写
- 默认情况下,只匹配初始目录,如果要精确匹配,配置exact属性为true
- 如果不写path,则会匹配任意路径
- component:匹配成功后要显示的组件
- children:
- 传递React元素,只有匹配到该,一定会显示children,并且会忽略component属性
- 传递一个函数,该函数有多个参数,这些参数来自于上下文,该函数返回react元素,则一定会显示返回的元素,并且忽略component属性
- exact:是否精确匹配
Switch组件
写到Switch组件中的Route组件,当匹配到第一个Route后,会立即停止匹配。
由于Switch组件会循环所有子元素,然后让每个子元素去完成匹配,若匹配到,则渲染对应的组件,然后停止循环。因此,不能在Switch的子元素中使用除Route外的其他组件。
widthRouter
Link
生成一个无刷新跳转的a元素。
- to
- 字符串:跳转的目标地址
- 对象:
- pathname:url路径
- search
- hash
- state:附加的状态信息
- replace:bool,表示是否是替换当前地址,默认是false
- innerRef:可以将内部的a元素的ref附着在传递的对象或函数参数上
- 函数
- ref对象
NavLink
是一种特殊的Link,Link组件具备的功能,它都有。 它具备的额外功能是:根据当前地址和链接地址,来决定该链接的样式
- activeClassName: 匹配时使用的类名
- activeStyle: 匹配时使用的内联样式
- exact: 是否精确匹配
- sensitive:匹配时是否区分大小写
- strict:是否严格匹配最后一个斜杠
Redirect
重定向组件,当加载到该组件时,会自动跳转(无刷新)到另外一个地址。
- to:跳转的地址
- 字符串
- 对象
- push: 默认为false,表示跳转使用替换的方式,设置为true后,则使用push的方式跳转
- from:当匹配到from地址规则时才进行跳转
- exact: 是否精确匹配from
- sensitive:from匹配时是否区分大小写
- strict:from是否严格匹配最后一个斜杠
路由信息
Router组件会创建一个上下文,并且,向上下文中注入一些信息
该上下文对开发者是隐藏的,Route组件若匹配到了地址,则会将这些上下文中的信息作为属性传入对应的组件
history
它并不是window.history对象,我们利用该对象无刷新跳转地址
为什么没有直接使用history对象
- React-Router中有两种模式:Hash、History,如果直接使用window.history,只能支持一种模式
- 当使用windows.history.pushState方法时,没有办法收到任何通知,将导致React无法知晓地址发生了变化,结果导致无法重新渲染组件
- push:将某个新的地址入栈(历史记录栈)
- 参数1:新的地址
- 参数2:可选,附带的状态数据
- replace:将某个新的地址替换掉当前栈中的地址
- go: 与window.history一致
- forward: 与window.history一致
- back: 与window.history一致
location
与history.location完全一致,是同一个对象,但是,与window.location不同
location对象中记录了当前地址的相关信息
我们通常使用第三方库query-string,用于解析地址栏中的数据
match
该对象中保存了,路由匹配的相关信息
- isExact:事实上,当前的路径和路由配置的路径是否是精确匹配的
- params:获取路径规则中对应的数据
实际上,在书写Route组件的path属性时,可以书写一个string pattern(字符串正则)
react-router使用了第三方库:Path-to-RegExp,该库的作用是,将一个字符串正则转换成一个真正的正则表达式。
向某个页面传递数据的方式:
- 使用state:在push页面时,加入state
- 利用search:把数据填写到地址栏中的?后
- 利用hash:把数据填写到hash后
- params:把数据填写到路径中
非路由组件获取路由信息
某些组件,并没有直接放到Route中,而是嵌套在其他普通组件中,因此,它的props中没有路由信息,如果这些组件需要获取到路由信息,可以使用下面两种方式:
- 将路由信息从父组件一层一层传递到子组件
- 使用react-router提供的高阶组件withRouter,包装要使用的组件,该高阶组件会返回一个新组件,新组件将向提供的组件注入路由信息。