美文网首页React.jsredux学习
简易Redux库的实现

简易Redux库的实现

作者: 难波六太 | 来源:发表于2019-03-28 14:08 被阅读10次

基础Redux实现

Redux的强大之处也由于它的简洁,我们甚至可以用几行代码来实现一个简易的Redux生态。

Redux将所有数据都存储再一个地方,即store,因此,我们要实现:

  1. 事件最终会修改state
  2. 监听state的改变好让我们能够改变UI

上述的第1点我们可以分成两个小部分来实现:

  1. 在action生成时通知store
  2. 为store实现修改state的逻辑(即代码)

根据以上描述,我们只使用html和javascript,不借助外部库,用Flux概念来构建一个简单的计数器,使用按钮可以增加和减少计数值。

index.html

<div>
  计数:
  <span id="counter"></span>
</div>
<button id="inc">增加</button>
<button id="dec">减少</button>

使用state来保存计数值

counter.js

let state = {
  counter: 3
}

在每个按钮的点击事件上来生成action,并使用dispatch(action)函数来分发

document.getElementById('inc').onclick = () => dispatch('INC')
document.getElementById('dec').onclick = () => dispatch('DEC')
// 在redux中 action中必须有tpe属性 在这里我们先简写 只传入一个代表增加或减少的字符串

function dispatch(action){
  // 待定 请继续阅读之后的部分
}

其次,我们需要定义更新html页面的代码

function updateView(){
  document.getElementById('counter').innerText = state.counter
}

由UI显示state中的值,即counter,那么我们需要在每次state变化时通知updateView()来及时更新html页面上的内容

subscribe(updateView)
// subscribe函数还未定义 在这里先使用 请继续阅读

至此,我们已经创建了计数器的基本结构。使用state来存储计数器的值,updateView函数来更新html,定义了两个函数dispatch和subscribe函数来分发action和监听state改变并通知updateView函数(即调用)。

但我们还没有实现处理事件的过程,这个简易Redux是如何在获得action,经历一些步骤后,来达到更改html的呢?为此我们还需要一个reducer函数,接受当前的state和action,来返回一个新的state,再用新的state来渲染html。

由于我们的action没有type属性,只是一个代表了增加或减少的字符串,我们的reducer实现如下

function reducer(state, action){
  switch(action){
    case 'INC':
      return { ...state, counter: state.counter + 1 }
    case 'DEC':
      return { ...state, counter: state.counter - 1 }
    default:
      return state
  }
}

重要的是,在state有变化时,reducer必须创建一个新的state,在新的state上根据action做出改动,并返回新的state。(新的state在js中可理解为不同的引用,state为一个object,js中两个结构和键值完全相同的object并不相等,因为他们在===比较时用的时引用,即内存地址)

用如下方式来改变state时错误的,因为state的内存地址没有变,store并不能检测到state的改变,随后会说明原因

state.counter = state.counter + 1

dispatch函数调用reducer函数来获取新的state,并通知updateView改变html

function dispatch(action){
  const newState = reducer(state, action)

  if(newState !== state){
    state = newState
    listeners.forEach(listener => listener())
  }
}

在if判断中,我们通过比较内存地址来得知state发生了改变,listeners为一个数组,里面包含了在state有变动时需要触发的函数,比如updateView

const listeners = []
function subscribe(callback){
  listeners.push(callback)
}

之前,我们已经用subscribe监听了updateView函数。至此,我们的简易Redux计数器完成了。我们可以点击按钮来增加和减少计数值。

document.getElementById('counter').innerText = document.getElementById('counter').innerText + 1

使用如上代码或许也能轻松实现该效果,但随着我们的应用逐渐扩大,所涉及的改动也越来越多,Flux设计模式的优势也将会逐渐凸显。

在Codepen上查看完整计数器应用

相关文章

  • 简易Redux库的实现

    基础Redux实现 Redux的强大之处也由于它的简洁,我们甚至可以用几行代码来实现一个简易的Redux生态。 R...

  • 简易Redux实现

    HTML模板如下 JavaScript代码如下 动手实现Redux

  • 自己实现Redux

    自己实现Redux 不使用react,直接使用原生的html/js来写一个简易的的redux 基本的状态管理及数据...

  • Redux实现简易Todolist

    React-Transition-Group React动画组件库 实现css3过渡动画效果 用法其实我没怎么看 ...

  • 20行代码实现redux,50行代码实现react-redux

    redux的简陋版实现 简单实现了下redux,帮助理解redux的原理: 实现了redux的createStor...

  • Redux for ReactNative (二)

    安装 React Redux Redux不包含React库,需要单独安装React 绑定库 react-redux...

  • redux实践体会

    最近在项目里实践了一把redux框架,有些感受记录一下。 框架的实现使用这个库Reductor: Redux fo...

  • co库的简易实现

    generator Generator 函数是 ES6 提供的一种异步编程解决方案。 执行generator函数会...

  • redux

    单独使用redux redux是核心库 与react配合使用redux 安装react-redux react-r...

  • reactHooks实现一个简易redux

    实现redux 顶层 createContext创建共享的上下文 useReducer使用类同redux 需要使用...

网友评论

    本文标题:简易Redux库的实现

    本文链接:https://www.haomeiwen.com/subject/dgyqbqtx.html