【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 会有一个初步认识
把下面整体代码运行,慢慢体会,点开控制台看结果
可以把下面代码复制 到一个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>