react 页面缓存插件react-router-cache-route
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react 页面缓存插件react-router-cache-route相关的知识,希望对你有一定的参考价值。
参考技术A 此插件可以满足缓存上一页的功能,即:返回上一页的时候,上一页的滚动条、动作状态等等和离开这个页面时的状态保持一致。搭配 react-router 工作的、带缓存功能的路由组件,类似于 Vue 中的 keep-alive 功能。
Route 中配置的组件在路径不匹配时会被卸载(render 方法中 return null),对应的真实节点也将从 dom 树中删除,利用Route暴露的children方法,让我们手动控制渲染。
注意:作者测试使用时版本为1.4.6
缓存语句不要写在 Switch 组件当中,因为 Switch组件会卸载掉所有非匹配状态下的路由,需使用 CacheSwitch 替代 Switch。
使用 when 属性决定何时使用缓存功能,可选值为 [forward, back, always] ,默认值为 forward。
使用 className 属性给包裹组件添加自定义样式。
也可以使用 behavior 属性来自定义缓存状态下组件的隐藏方式,工作方式是根据 CacheRoute 当前的缓存状态,返回一个作用于包裹组件的 props。
使用 CacheRoute 的组件将会得到一个名为 cacheLifecycles 的属性,里面包含两个额外生命周期的注入函数 didCache 和 didRecover,分别用在组件 被缓存 和 被恢复 时
github地址
react-router详细解释
react-router的理解
react的一个插件库,专门用来实现一个SPA应用(单页Web应用(single page web application,SPA)整个应用只有一个完整的页面,点击页面中的链接不会刷新页面, 本身也不会向服务器发请求,当点击路由链接时, 只会做页面的局部更新)
基于react的项目基本都会用到此库。react-router针对不同的使用场景衍生了不同的路由包,RN项目用react-router-native,web项目用react-router-dom。并且,不需要再重复引入react-router了。
路由的理解
一个路由就是一个映射关系(key:value)。key为路由路径, value可能是function/component(某个对象的组件)
后台路由
node服务器端路由, value是function, 用来处理客户端提交的请求并返回一个响应数据
注册路由 router.get(path, function(req, res))。当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
前台路由
浏览器端路由, value是component, 当请求的是路由path时, 浏览器端前没有发送http请求, 但界面会更新显示对应的组件
注册路由: <Route path="/about" component={About}>。当浏览器的hash变为#about时, 当前路由组件就会变为About组件
前端路由的实现
history库:管理浏览器会话历史(history)的工具库。包装的是原生BOM中window.history和window.location.hash
history API:
History.createBrowserHistory(): 得到封装window.history的管理对象
History.createHashHistory(): 得到封装window.location.hash的管理对象
history.push(): 添加一个新的历史记录
history.replace(): 用一个新的历史记录替换当前的记录
history.goBack(): 回退到上一个历史记录
history.goForword(): 前进到下一个历史记录
history.listen(function(location){}): 监视历史记录的变化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>history test</title> </head> <body> <p><input type="text"></p> <a href="/test1" onclick="return push(‘/test1‘)">test1</a><br><br> <button onClick="push(‘/test2‘)">push test2</button><br><br> <button onClick="back()">回退</button><br><br> <button onClick="forword()">前进</button><br><br> <button onClick="replace(‘/test3‘)">replace test3</button><br><br> <script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script> <script type="text/javascript"> let history = History.createBrowserHistory() // 方式一 history = History.createHashHistory() // 方式二 // console.log(history) // 希望能回退使用这个方法 function push (to) { history.push(to) return false // 让a标签的默认行为失效 } function back() { history.goBack() } function forword() { history.goForward() } // 希望不可以回退使用这个方法 function replace (to) { history.replace(to) } history.listen((location) => { console.log(‘请求路由路径变化了‘, location) }) </script> </body> </html>
react-router相关API以及基本使用
搭建一个应用,目录结构何文件如下
实现这样的一个简单的效果
项目中下载react-router: npm install --save react-router-dom
首先在index.js文件中使用路由管理整个应用
import React from ‘react‘; import ReactDOM from ‘react-dom‘; import {BrowserRouter, HashRouter} from ‘react-router-dom‘ import ‘./index.css‘; import App from ‘./App‘; ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter> ), document.getElementById(‘root‘)); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA
或者可以使用HashRouter模式
import React from ‘react‘; import ReactDOM from ‘react-dom‘; import {BrowserRouter, HashRouter} from ‘react-router-dom‘ import ‘./index.css‘; import App from ‘./App‘; ReactDOM.render(( <HashRouter> <App /> </HashRouter> ), document.getElementById(‘root‘)); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA
然后创建测试路由的模块页面,并且在App.js(项目入口文件)中引入
import React, { Component } from ‘react‘; import ‘./App.css‘; import RouterTest from ‘./views/router-test/router-test‘ class App extends Component { render() { return ( <div className="App"> <RouterTest/> </div> ); } } export default App;
路由测试mokrouter-test.js中使用<NavLink/>来包裹路由连接,并且使用<Switch>来匹配路由组件,<Redirect/>设置一打开就定向到某个路由
import React, { Component } from ‘react‘; import {NavLink, Switch, Route, Redirect} from ‘react-router-dom‘ import ‘./router-test.css‘; import About from ‘../about/about‘ import Home from ‘../home/home‘ class RouterTest extends Component { render() { return ( <div className="router-test"> <div className=‘router-list‘> <NavLink className=‘router-list-group‘ to=‘/home‘>HOME</NavLink> <NavLink className=‘router-list-group‘ to=‘/about‘>ABOUT</NavLink> </div> <div className=‘router-content‘> <Switch> <Route path=‘/about‘ component={About} /> <Route path=‘/home‘ component={Home} /> <Redirect to=‘/home‘/> </Switch> </div> </div> ); } } export default RouterTest;
about.js组件
import React, { Component } from ‘react‘; import ‘./about.css‘; class About extends Component { render() { return ( <div className="about"> about </div> ); } } export default About;
home.js组件
import React, { Component } from ‘react‘; import ‘./home.css‘; class Home extends Component { render() { return ( <div className="home"> home </div> ); } } export default Home;
运行后,<NavLink/>标签会解析成a标签,当前激活的那个路由,会有一个class类:active,这个类可以自定义,然后可以在activeClass类中编写样式
<NavLink className=‘router-list-group‘ activeClassName=‘activeClass‘ to=‘/home‘>HOME</NavLink> <NavLink className=‘router-list-group‘ activeClassName=‘activeClass‘ to=‘/about‘>ABOUT</NavLink>
但是这样每个路由链接都要这样写一个自定义类很麻烦,这时候我们可以将NavLink组件包装一下,定义一个公共组件
编写my-nav-link.js组件
import React from ‘react‘ import {NavLink} from ‘react-router-dom‘ export default function MyNavLink(props) { /*包装一个现有的组件,{...props}表示接收任何属性*/ return <NavLink {...props} activeClassName=‘activeClass‘/> }
然后应用这个公共的组件
import React, { Component } from ‘react‘; import {Switch, Route, Redirect} from ‘react-router-dom‘ import MyNavLink from ‘../../components/my-nav-link/my-nav-link‘ import ‘./router-test.css‘; import About from ‘../about/about‘ import Home from ‘../home/home‘ class RouterTest extends Component { render() { return ( <div className="router-test"> <div className=‘router-list‘> <MyNavLink className=‘router-list-group‘ to=‘/home‘>HOME</MyNavLink> <MyNavLink className=‘router-list-group‘ to=‘/about‘>ABOUT</MyNavLink> </div> <div className=‘router-content‘> <Switch> <Route path=‘/about‘ component={About} /> <Route path=‘/home‘ component={Home} /> <Redirect to=‘/home‘/> </Switch> </div> </div> ); } } export default RouterTest;
运行结果显示,当前激活的路由就会带上activeClass这个类
路由的嵌套
向路由组件传递数据
以上是关于react 页面缓存插件react-router-cache-route的主要内容,如果未能解决你的问题,请参考以下文章
react缓存页面react-keepalive-router