vlambda博客
学习文章列表

【redux源码分析】通过原生js手写实现redux来理解redux的数据响应


想要把源码掰开揉碎,我们先从观察者模式一点一点分析


源码中的



【redux源码分析】通过原生js手写实现redux来理解redux的数据响应

我们先用原生代码实现一个观察者模式

创建一个工厂函数 createStore


返回三个函数

  getState  获取状态
dispatch 用来触发Action
subscribe 订阅

createStore 工厂函数

const createStore = (reducer) => {
let state;
let listeners = [];

// 纯函数返回当前的state
const getState = () => state

// 定义一个dispatch 用来触发action
const dispatch = (action) => {
//通过调用传进来的reducer函数来修改state
//返回新的状态并赋值给state
state = reducer(state, action);
}

//订阅状态
const subscribe = function (data) {
//先把此监听 加到数组中
listeners.push(data);
//返回一个函数,当调用它的时候将此监听函数从监听数组移除
return function () {
listeners = listeners.filter(v => v != data);
}
}

//初始化的时候 调用一次dispatch给state赋一个默认值
dispatch({ type: 'stark' }) // 初始化全局状态

// 返回三个方法
return {
getState,
dispatch,
subscribe
}
}

创建一个 reducer


const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'MIN':
return state - 1
default:
return 10
}
}

应用创建 store


let store = createStore(reducer);

获取状态


const init = store.getState()

把数据渲染到界面上


const render = () => {
document.body.innerText = store.getState()
}

订阅


store.subscribe(render);

调用 render();


render();

定义类型


let INCREASE_ACTION = { type: 'INCREMENT' };

点击文档触发一个Action


document.addEventListener('click', function (e) {
//触发一个Action
store.dispatch(INCREASE_ACTION);
})

有问题继续留言

 

源码地址:


http://github.com/wsdo/redux.git

通过这个例子,我们慢慢理解redux 会有一个初步认识

把下面整体代码运行,慢慢体会,点开控制台看结果


【redux源码分析】通过原生js手写实现redux来理解redux的数据响应

可以把下面代码复制 到一个HTML 文件里面来,自己运行


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script ></script>
</head>
<body>

</body>
<script>

const createStore = (reducer) => {
let state; // 定义存储的state
let listeners = [];

const getState = () => state;

const dispatch = (action) => {
console.log('====================================')
console.log('action', action)
console.log('state', state)
console.log('====================================')
state = reducer(state, action);
// listeners.forEach(listener => listener());
}

const subscribe = function (listener) {
listeners.push(listener);
console.log('====================================')
console.log(listeners)
console.log('====================================')

return function () {
listeners = listeners.filter(v => v != listener);
}
}

dispatch({ type: 'stark' }) // 初始化全局状态
return {
getState,
dispatch,
subscribe
}
}

const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'MIN':
return state - 1
default:
return 10
}
}

let store = createStore(reducer);
const init = store.getState()
console.log('====================================')
console.log(init)
console.log('====================================')

//把数据渲染到界面上
const render = () => {
document.body.innerText = store.getState()
}

// 订阅
store.subscribe(render);
render();
var INCREASE_ACTION = { type: 'INCREMENT' };
document.addEventListener('click', function (e) {
//触发一个Action
store.dispatch(INCREASE_ACTION);
})

</script>
</html>