内容简介:把之前学习redux的手写学习笔记分享出来一下,方便大家理解redux思想,毕竟前端工程师里面都说,这个是将redux思想的一个拆分, 将 redux 拆分成 5 部分,最终拼成一个react redux,有了redux之后 state不再是谁都可以任意调用setState修改的数据了,
把之前学习redux的手写学习笔记分享出来一下,方便大家理解redux思想,毕竟前端工程师里面都说,
初级前端和中级前端的区别就是是否懂 设计模式 和面向对象
这个是将redux思想的一个拆分, 将 redux 拆分成 5 部分,最终拼成一个react redux,
为什么使用react redux ?
有了redux之后 state不再是谁都可以任意调用setState修改的数据了,
react: 通过 setState修改state数据,再执行渲染;
react-redux: 通过 dispatch来判断是否执行setState,dispatch检测通过,执行setState函数, 否则不予执行;
1. 引入dispatch管理对setState的调用
<div id="title"></div> <div id="contents"></div> <script> // 渲染模块 function render() { document.getElementById('title').innerHTML = state.title; document.getElementById('contents').innerHTML = state.content; } //数据模块 var state = { title: '新的标题', content: '新的内容' } //初次渲染执行 render(); //更改数据模块 ** 更改后触发数据渲染 function setState(newState) { this.state = { ...state, ...newState } render() } </script> 复制代码
下面这部分是redux思想的和体现方式, 通过dispath判断参数的type是否合法, 合法才可以可以调用setState
<script> // 管理模块, 想要触发数据改变请执行这个函数, 并且要给指定的type, 否则不执行setState var dispatch = function (action) { switch (action.type) { case 'CHANGE_TITLE': // 传过来的type正确才能setState setState({ title: action.newTitle }) break; default: break; } } //修改数据调用dispatch函数, 只有里面的json的type经过了dispatch检测才能执行相应的setState dispatch( { type: 'CHANGE_TITLE', newTitle: '我是经过dispatch函数允许修改后的新标题' } ) </script> 复制代码
2. 引入subscriber
<div id="title"></div> <div id="contents"></div> <script> function render() { document.getElementById('title').innerHTML = state.title; document.getElementById('contents').innerHTML = state.content; } var state = { title: '新的标题', content: '新的内容' } render() 复制代码
创建数组listeners, 引入订阅subscriber 函数,该函数向数组中订阅(push)新的事件,比如render渲染函数,在成功触发setState后,会对listensers数组里面的函数依次执行。
var dispatch = function (action) { switch (action.type) { case 'CHANGE_TITLE': state = { ...state, title:action.newTitle } break; default: break; } listeners.forEach(e=>e()) //依次执行数组中订阅的事件 } var listeners = []; //这个数组放setState之后执行的事件, var subscribe = function(listener){ //用subscriber函数把事件push到事件数组中 listeners.push(listener) } subscribe(render) // 数组中放入render函数 dispatch( { type: 'CHANGE_TITLE', newTitle: '我是经过dispatch函数允许修改后的新标题' } ) </script> </body> 复制代码
3. 初步封装 createStore
div id="title"></div> <div id="contents"></div> <script> //渲染函数 function render(state) { document.getElementById('title').innerHTML = state.title; document.getElementById('contents').innerHTML = state.content; } //store 核心部分 var createStore = function () { //state数据 var state = { title: '这是一个标题', content: '这是一段内容' } //执行函数仓库 var listeners = []; //获取state数据 var getState = function () { return state; } //dispatch监控 type是否合法,合法才触发setState函数 var dispatch = function (action) { switch (action.type) { case 'CHANGE_TITLE': state = { ...state, title: action.newTitle } break; default: break; } listeners.forEach(e => e()) } //事件订阅函数 var subscribe = function (listener) { listeners.push(listener) } // 暴露调用接口 return { dispatch, subscribe, getState } } //调用部分 //创建实例化对象 var store = createStore(); //解构获取三个接口函数 var { subscribe, dispatch, getState } = store; //订阅事件 subscribe(() => render(getState())); //请求dispatch改变状态 dispatch( { type: 'CHANGE_TITLE', newTitle: '我是经过dispatch函数允许修改后的新标题' } ) render(getState()) </script> 复制代码
但是这个createStore函数存在不纯的问题,含有定好的state 和 dispatch,接下来就是对该函数进行提纯处理。
4. createStore函数提纯处理,让createStore 和 state,setState相分离 , 将state和setState放入appReducer函数中
<div id="title"></div> <div id="contents"></div> <script> //store 核心部分 var createStore = function () { // 将state设置为 null; var state = null var listeners = []; var dispatch = function (action) { //调用dispatch时, 执行appReducer做判断 state = appReducer(state, action); listeners.forEach(e => e()); } //调用dispatch初始化state,获取appReducer中的默认state。 dispatch({}) var subscribe = function (listener) { listeners.push(listener) } var getState = function () { return state; } //暴露接口 return { dispatch, subscribe, getState } } var appReducer = function (state, action) { //初始化store中的state //因为state初始值为null if (!state) { return { title: '这是一个标题', content: '这是一段内容' } } //更新state switch (action.type) { case 'CHANGE_TITLE': return { ...state, title: action.newTitle } break; default: return state; } } var store = createStore(); var { subscribe, dispatch, getState } = store; subscribe(() => render(getState())) dispatch( { type: 'CHANGE_TITLE', newTitle: '我是经过dispatch函数允许修改后的新标题' } ) function render(state) { document.getElementById('title').innerHTML = state.title; document.getElementById('contents').innerHTML = state.content; } //调用部分 render(getState()) </script> 复制代码
此时 createStore依然不是一个纯函数, 依然无法独立, 因为里面有写死的appReducer函数的执行;
5. 彻底让createStore变成纯构造函数 , appReducer作为参数传入到createStore。
// 现在已经是非常干净的纯构造函数了 function createStore(appReducer) { state = null; var listeners = []; function dispatch(action) { state = appReducer(state, action) listeners.map(e => e()) } dispatch({}) function getState() { return state } function subscribe(listener) { listeners.push(listener); } return { dispatch, getState, subscribe } } // appReucer 函数 function appReducer(state, action) { //初始化数据 if (!state) { return { title: '你好', content: '欢迎光临' } } switch (action.type) { case 'CHANGE_TITLE': return { ...state, title: action.newTitle } break; default: break; } } //使用createStore部分 var store = createStore(appReducer); var { dispatch, getState, subscribe } = store; subscribe(() => render(getState())) dispatch( { type: "CHANGE_TITLE", newTitle: '我是经过dispatch函数允许修改后的新标题' } ) function render(state) { document.getElementById('title').innerHTML = state.title; document.getElementById('content').innerHTML = state.content; } render(getState()); 复制代码
以上所述就是小编给大家介绍的《从 0 到 1 理解 React redux 的设计思想 (5步分解, 保证小白都能看得懂)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 算法学习:常用设计思想
- flex设计思想和语法简介
- 16 种设计思想 – Design for failure
- 设计开发中要避免的两个坑和一种可借鉴的设计思想
- 宜信开源|Wormhole 大数据流式处理平台之设计思想
- 彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。