迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言: 续上篇前端的状态管理(上),没想到很多读者朋友们这么关注,感谢大家的支持和建议,我只是发表个人看法以及自己的一些思考也许不够全面,使用 Vue 举例也仅仅只是作为引路且 Vue 的关注度也是较高的。那有些朋友想听听除 Vuex 的其他方案,今天将从 Redux 入手逐渐拓展(如标题一样浅谈)。 1、Redux作为 Redux 的基础操作大致为:
1.1、Store(图书馆管理员)
import { createStore } from 'redux' const store = createStore(reducer); 1.2、State(书本)对于 使用 import { createStore } from 'redux' const store = createStore(reducer) store.getState() 1.3、Action(借书单)你想借书咋办?那当然是向管理员提交借书单了。那用户是接触不到
const action = { type: 'click', info: '提交借书单' } 1.4、store.dispatch (提交借书单)
store.dispatch(action) 1.5、Reducer(包装书本)
const reducer = (state, action) => { return `action.info: ${state}` // => 提交借书单:红楼梦 } store.subscribe(接收书本) 当 State 一旦发生变化,那么 store.subscribe() 就会监听到自动执行更新 View。 const unsubscribe = store.subscribe(() => { render() { // 更新view } }) // 也可以取消订阅(监听) unsubscribe() 小结: 相信刚接触 尽管在
至于为什么要这么做,上一篇我已有提及。他的重要之处在于:便于应用的测试,错误诊断和 2、状态管理的目的那其实大多数程序员使用 Redux 的最多的场景无非是从 A 页面返回 B 页面 需要保存 B 页面的状态。 倘若项目不大,用 但是很遗憾在 还是用图书馆来举例子,现在有一个图书馆管理系统,你从列表页(list)跳入详情页( 假设你使用的技术栈是( // KeepAlive.js export default function keepAliveWrapper() { return function keepAlive(WrappedComponent) { return class KeepAlive extends WrappedComponent { // ps constructor(props) { super(props) // do something ... } componentDidMount() { const { keepAlive: { fieldsValue }, } = this.context // do something ... super.componentDidMount() } render() { // do something ... return super.render() } } } } 这里提一下为什么要继承原组件 如果常规写法返回一个类组件( 若使 // main.jsx 根组件 import React from 'react' const appContext = React.createContext() class App extends React.Component { constructor(props) { super(props) this.state = { keepAlive: {}, // 缓存对象 isCache: false, // 是否缓存 fieldsValue: {} // 缓存表单值 } } componentDidMount() { // 初始化 const keepAlive = { isCache: this.state.isCache, toggle: this.toggleCache.bind(this), fieldsValue: this.state.fieldsValue, } this.setState({ keepAlive }) } // 这里封装一个清除状态的方法 防止渲染警告(you can't set fields before render ...) // 比如 list1 => list1/detail => list2 需要将跳转放在以下回调中并清除状态 toggleCache(isCache = false, payload, callback) { const { fieldsValue = null } = payload const keepAlive = { isCache, fieldsValue, toggle: this.toggleCache.bind(this), } const fn = typeof callback === 'function' ? callback() : void 0 this.setState( { keepAlive, }, () => { fn } ) } render() { const { keepAlive } = this.state <appContext.Provider value={{ keepAlive }}> // your routes... </appContext.Provider> } } 至于为什么不直接使用 // 在页面使用时 import React from 'react' import keepAlive from '../keepAlive' // keepAlive的位置需要放在原组件最近的地方 @keepAlive() class App extends React.Component { constructor(props){ super(props) this.state = { // init something... } } componentDidMount() { // do something... if(this.context.keepAlive.fieldsValue) { const { tableList } = this.context.keepAlive.fieldsValue console.log('缓存啦:',tableList) // 缓存啦:['1', '2'] } } // 查看详情 detail = () => { this.context.keepAlive.fieldsValue = { tableList: ['1', '2'] } // jump... } // 当需要跨一级路由进行跳转时,如 list1 => list1/detail(下面这个方法应该在详情页里) => list2,此时需要处理一下警告 toList2 = () => { this.context.keepAlive.toggle(false, {}, () => { // jump... }) } } 在上述使用了装饰器写法,简单说一下,需要先配置以下
在 { "compilerOptions": { "experimentalDecorators": true }, "exclude": [ "node_modules", "dist" ] } 在 .babelrc 配置: { "plugins": [ "@babel/plugin-proposal-decorators", { "legacy": true } ] } 上面方法比较适用刚才说的场景(从 A 页面返回 B 页面 需要保存 B 页面的状态),有人的说,你这样还不如用 总结: 到此这篇关于前端的状态管理的文章就介绍到这了,更多相关前端的状态管理内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! 回顾上篇:浅谈前端的状态管理(上) |
请发表评论