数据流程
view通过dispatch触发action,store监听到action,通过reducer更新计算数据,然后再更新view
import './App.css';
import { createStore } from 'redux';
function renducer(state={count:0},action){
switch (action.type) {
case "ADD_TODO":
return {...state,count:state.count+1}
default:
return state
}
}
const store=createStore(renducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
function click(){
store.dispatch({
type: 'ADD_TODO',
payload: 'Learn Redux'
});
}
store.subscribe(()=>{
console.log(store.getState(),'22')
});
function App() {
return (
<div className="App">
{store.getState().count}
<div onClick={click}>点击</div>
</div>
);
}
export default App;
createStore简单实现
let state;
let listeners = [];
const getState = () => state;
const dispatch = (action) => {
state = reducer(state, action);
listeners.forEach(listener => listener());
};
const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter(l => l !== listener);
}
};
dispatch({});
return { getState, dispatch, subscribe };
};
combineReducers用法
function renducer(state={count:0},action){
switch (action.type) {
case "ADD_TODO":
return {...state,count:state.count+1}
default:
return state
}
}
function renducer1(state={count1:0},action){
switch (action.type) {
case "ADD_TODO1":
return {...state,count:state.count1+1}
default:
return state
}
}
const dd=combineReducers({
renducer,
renducer1
})
const store=createStore(dd, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
下面是combineReducer的简单实现。
return (state = {}, action) => {
return Object.keys(reducers).reduce(
(nextState, key) => {
nextState[key] = reducers[key](state[key], action);
return nextState;
},
{}
);
};
};
中间件
但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。
怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。
上面代码中,applyMiddleware方法的三个参数,就是三个中间件。有的中间件有次序要求,使用前要查一下文档。比如,logger就一定要放在最后,否则输出结果会不正确。
看到这里,你可能会问,applyMiddlewares这个方法到底是干什么的?
它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。下面是它的源码。
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer);
var dispatch = store.dispatch;
var chain = [];
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
};
chain = middlewares.map(middleware => middleware(middlewareAPI));
dispatch = compose(...chain)(store.dispatch);
return {...store, dispatch}
}
}
上面代码中,所有中间件被放进了一个数组chain,然后嵌套执行,最后执行store.dispatch。可以看到,中间件内部(middlewareAPI)可以拿到getState和dispatch这两个方法。
react-thunk
action可以接收异步函数
redux-promise
阮老师文档
juejin.cn/post/684490… redux基本实现