简介
实现一个简单的Redux,以便更好地理解Redux
state
coust state = {
count:1
}
state.count = 2
console.log(state.count)//2这样就可以直接改变state里面的值,但是改变state里面的值后没有人知道呀,所以引入发布订阅模式
subcribe
const listeners = []
function subscribe(listener){
listeners.push(listener)
}
subcribe(()=>{
state.count = count
})
function setCount(count){
state.count = count
listeners.forEach(item=>item())
}
setCount(2)//2
setCount(3)//3这样就知道改变数据了
代码封装
function createStore(initState) {
let state = initState
let listeners = []
//订阅
function subscribe(listener) {
listeners.push(listener)
}
function changeState(newState) {
listeners.forEach(item=>item())
state = newState
}
function getState() {
return state
}
return {
subscribe,
changeState,
getState
}
}接下来创建一个store
let store = createStore(initState)
store.subscribe(() => {
let state = store.getState();
console.log(`${state.user.name}:${state.user.age}`);
});
store.subscribe(() => {
let state = store.getState();
console.log(state.counter.count);
});
store.changeState({
...store.getState(),
user: {
name: 'qweqweqwe',
age: '1212'
}
});
store.changeState({
...store.getState(),
counter: {
count: 12222
}
});reducer和action
改造如下
function createStore(initState, reducer) {
let state = initState
let listeners = []
//订阅
function subscribe(listener) {
listeners.push(listener)
}
function dispatch(action) {
listeners.forEach(item => item())
state = reducer(state, action)
}
function getState() {
return state
}
return {
subscribe,
dispatch,
getState
}
}
let initState = {
count: 0
}
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1
}
break;
case 'DECREMENT':
return {
...state,
count: state.count - 1
}
break;
default:
break;
}
}
let store = createStore(initState, reducer)
store.dispatch({
type: 'INCREMENT'
})
store.dispatch({
type: 'INCREMENT'
})
store.dispatch({
type: 'DECREMENT'
})中间件
中间件是对dispatch的一个加强,下面是一个例子
记录日志中间件
//重写了dispatch方法,先用next缓存之前的dispatch方法
let store = createStore(initState, reducer)
let next = store.dispatch
store.dispatch = action => {
console.log(`action:${action}`)
console.log(`state:${store.getState()}`)
next(action)
console.log(`next state : ${store.getState()}`)
}记录异常
let store = createStore(initState, reducer)
let next = store.dispatch
store.dispatch = action => {
try{
next(action)
}catch(e){
throw new Error(e)
}
}多中间件合作
function createStore(initState, reducer) {
let state = initState
let listeners = []
//订阅
function subscribe(listener) {
listeners.push(listener)
}
function dispatch(action) {
listeners.forEach(item => item())
state = reducer(state, action)
}
function getState() {
return state
}
return {
subscribe,
dispatch,
getState
}
}
let initState = {
count: 0
}
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1
}
break;
case 'DECREMENT':
return {
...state,
count: state.count - 1
}
break;
default:
break;
}
}
let store = createStore(initState, reducer)
let next = store.dispatch
const loggerMiddleware = function (next) {
return function (action) {
console.log('this state', store.getState());
console.log('action', action);
next(action);
console.log('next state', store.getState());
}
}
const exceptionMiddleware = function (next) {
return function (action) {
try {
next(action);
} catch (err) {
console.error('错误报告: ', err)
}
}
}
store.dispatch = exceptionMiddleware(loggerMiddleware(next))
store.dispatch({
type: 'INCREMENT'
})
console.log(store.getState())不太理解的可以在浏览器debugger一遍,过程就很清晰了

京公网安备 11010502036488号