真正有用的看起来也就5个
applyMiddleware.js // 中间件
bindActionCreators.js // 工具函数
combineReducers.js // 工具函数
compose.js // 工具函数
createStore.js // 核心入口
基本使用方法在本文中不会涉及
可自定义拦截action -> reducer 的过程。变为 action -> middlewares -> reducer。可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能。
比如使用redux-thunk,就是引入thunkMiddleware,然后作为createStore的第二个参数applyMiddleware一下:
const store = createStore(reducer, applyMiddleware(thunkMiddleware))
Redux官方文档_异步 Action:https://www.redux.org.cn/docs/advanced/AsyncActions.html
异步 Action即处理异步逻辑,据说几乎是 React 面试中必问的一道题;
提前说好,听起来异步Action好像有点厉害,终究是把dispatch一个Action内部弄成dispatch好几个普通Action,直接看个异步fetch data的代码感受一下:
const fetchData = url => (dispatch, getState) =>{
// 1
dispatch({ type: 'loading', payload: true })
// 异步出现了!
fetch(url).then((response) => {
// 2
dispatch({ type: 'data', payload: response })
dispatch({ type: 'loading', payload: false })
}).catch((err) => {
// 3
dispatch({ type: 'error', payload: err.message })
dispatch({ type: 'loading', payload: false })
})
}
这是redux-thunk里处理异步的示例代码,中间件允许action是个(dispatch, getState)函数,直接dispatch这个fetchData(url)就行了;
对于1个异步请求,上面的3次state修改显然要dispatch 3个action才能完成。
假设在 React 函数式组件中去实现,代码大概为:
终究还是使用了3个同步Action 完成异步请求。Store 仅仅作为数据存放的地方,Redux 并不关心数据哪里来。
想要复用以上逻辑,可以包装为一个函数fetchData,然后把他dispatch了(前提是已经使用了redux-thunk中间件)
所以说异步 Action 并不是一个具体的概念,而可以看作是 Redux 的一个使用模式。它通过组合同步 Action ,用现有的方式提供了处理异步逻辑的方案。
Flux 的核心特征是单向数据流;
在许多服务端的 MVC 应用中,数据流确实能够保持单向。但是在前端场景下,实际的 MVC 应用要复杂不少,前端应用/框架往往出于交互的需要,允许 View 和 Model 直接通信,这也就导致了双向数据流的存在。当业务复杂度较高时,数据流会变得非常混乱
Action→Controller-<多个Model≡⋚⋛≡多个View
MV之间可达到全连接;而一个应用中还可能存在多个 Controller……
在单向数据流下,状态的变化是可预测的。如果 store 中的数据发生了变化,那么有且仅有一个原因,那就是由 Dispatcher 派发 Action 来触发的。
不敢多看Flux,怕把Redux学混淆了,以下仅供参考:
前文提及的useSelector
和useDispatch
是react-redux提供的hook函数
而useReducer
是react官方提供的内置hook函数,使用方法如下;
const [state, dispatch] = useReducer(reducer, initialState);
实际上,把useReducer
返回的state
和dispatch
函数存入全局的Context中并与useContext, useReducer
组合,可以模拟出一个简易的Redux,参考:
https://blog.csdn.net/weixin_34198797/article/details/91466007
https://segmentfault.com/a/1190000018345798