三、Redux
3.1 reducer规则
1.Reducers 必须始终遵循一些特定的规则:
他们应该只根据state和action参数计算新的状态值
他们不允许修改现有的state. 相反,他们必须通过复制现有值并对复制的值进行更改来进行不可变的更新state。
它们不得执行任何异步逻辑、计算随机值或导致其他“副作用”
在default情况下返回旧的state。
2.reducer判断state是否变化从而更新的方式:
不要直接修改原来的state,要创建副本state的原因:在redux-devtools中,我们可以查看到redux下所有通过reducer更新state的记录,每一个记录都对应
着内存中某一个具体的state,让用户可以追溯到每一次历史操作产生与执行时,当时的具体状态,这也是使用redux管理状态的重要优势之一.
展开运算符只是一个浅拷贝。
深拷贝方案:
(1) object.assign()
(2) 展开运算符(属性为对象的话需要对属性再次使用展开运算符以实现深拷贝)
(3) 采用lodash的cloneDeep方法
(4) 采用官方提供的Immutability Helper工具中update()方法进行数据更新
3.2 使用useContext和useReducer实现的状态管理
(1)const myContext =React.createContext(data);
(2)const [store,dispatch] = useReducer(reducer,initialState);
(3)<mycontext.Provider value= {state, dispatch}>
<App />
</mycontext.Provider>
(4) 子组件中使用dispatch触发action从而更新
const context = useContext(myContext);
const dispatch = context.dispatch;
<button onClick={() => dispatch({ type: ‘COMPLETE_TODO’, taskname: item.taskname })}>完成}
3.3 redux实现的状态管理
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL5lkeNh3aE90dRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3cDMlNGZhF2MjJWMzkDZ4QjZwQzN3YGNmlzYiVmN4EzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
store.subscribe(fn):注册监听器,即监听store,store发生变化(即每次调用完dispatch)的话那么就会执行fn。
四、 react-redux:provider和connect(redux进阶)
4.1 容器组件和展示组件
展示组件:不使用redux,只展示组件的样式和结构,数据来源是props
容器组件:直接使用redux,数据获取,状态更新,数据来源是监听Redux,state,使用connect生成。
4.2 createStore
const store = createStore(reducer,initialState);
4.3 Provider
父组件注入Store
<App />
4.4.connect 高阶组件
实际上 connect 就是一个高阶组件,它将组件包装之后拿到一个能够在组件中直接获取 context 的 state 的组件,子组件使用state
4.5 使用 PropTypes 进行类型检查(完善项目)
import PropTypes from ‘prop-types’;
五、(react-thunk)网络请求异步action
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === ‘function’) {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
它的核心代码其实只有两行,就是判断每个经过它的action:如果是function类型,就调用这个function(并传入 dispatch 和 getState 及 extraArgument 为参数),而不是任由让它到达 reducer,因为 reducer 是个纯函数,Redux 规定到达 reducer 的 action 必须是一个 plain object 类型。