redux核心知识
一、redux的核心概念
Provider
作用:把父组件传递进来的store对象放入react 上下文中,这样connect组件就可以从上下文中获取到store对象
Connect
作用:
1.从react上下文中取出store对象,订阅store.state的变化,当store state变化时调用自身的一个方法重新生成connect组件的state,被包装组件便会被重新渲染。
2.获取store中的state,然后把被包装组件需要的state以属性的方式进行传递;
3.connect中可封装发送action的逻辑,对被包装组件来说需要更新store.state时,只需要调用connect传进来的某个属性即可,不会感知到store的存在,不直接接触dispatch(非必须的)
dispatch
触发store修改state的命令,是createStore返回对象的一个方法
action
dispatch携带的数据,描述要做什么操作的plan object,标准的写法是对象中有一个type和payload(携带数据用的)
bindActionCreators
作用是将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容
const mapDispatchToProps = dispatch => ({
...bindActionCreators({
init,
normalInit,
perspectiveAnalyse,
updateDataSetStatus,
create
}, dispatch)
});
const Capp = connect(mapStateToProps, mapDispatchToProps)(App);
//app.jsx组件 export function App(props){ //原来需要props.dispatch({type:'aaa'}) props.init('aaa'); }
reducer
根据action修改state后返回新的state
combineReducer
store.state进行分片管理,每个reducer管理state中的一部分。由于createStore只接受一个reducer,所以采用该方法生成一个最终的reducer
middleware
在 Redux 中,中间件的核心概念是“增强的 dispatch 函数”,当我们 dispatch 一个 action 时,中间件可以拦截该 action,对其进行处理,并再次将其传递给下一个中间件,最后再达到 reducer 进行状态的更新。
实现方式上通过利用函数嵌套和闭包的特性实现了链式调用。
/* *中间件的定义 第一层函数用于初始化中间件,并接受 store 对象作为参数。它会返回一个函数,作为中间件的入口函数,用于控制整个中间件的执行。 第二层函数是中间件的核心函数,它接受 next 参数,用于控制下一个中间件或默认的派发过程的调用。在这里,你可以执行一些在派发 action 前和后的自定义逻辑。 第三层函数是通过调用 next(action) 来将 action 传递给下一个中间件或默认的派发过程,并返回最终的结果。 使用这种函数柯里化的方式,可以方便地组合和扩展多个中间件,以实现灵活的中间件流水线。同时,每一层函数也可以在执行过程中对数据进行处理和加工,实现更复杂的功能。 */ const middleware1 = store => next => action => { console.log('Middleware 1 - Before dispatch:', action); // 在派发 action 前执行特定的逻辑 // 调用下一个中间件或者派发 action 的默认方法 const result = next(action); // 在派发 action 后执行特定的逻辑 return result; }; //使用中间件 const applyMiddleware = (...middlewares) => (createStore) => (reducer) => { const store = createStore(reducer); let dispatch = store.dispatch; // 为每个中间件传递 store 的引用 const middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action), }; // 生成中间件实例 const chain = middlewares.map((middleware) => middleware(middlewareAPI)); // 使用嵌套函数,将各中间件包装成一个洋葱圈调用模型 dispatch = compose(...chain)(store.dispatch); // 返回增强的 store return { ...store, dispatch, }; }; /** *将多个函数以从右到左的方式进行组合,将最右侧的函数的结果作为前一个函数的参数 */ function compose(...funcs) { if (funcs.length === 0) { return arg => arg; } if (funcs.length === 1) { return funcs[0]; } return funcs.reduce((a, b) => (...args) => a(b(...args))); }
二、redux的缺点
一、上手成本高
本身只提供了同步更新数据的功能,若想使用异步数据流,得自己集成redux-thunk、redux-saga之类的中间件
语法啰嗦,数据状态和数据更新的逻辑分散在不同的文件中,不利于维护
状态对象是不可变的,每次更新状态都需要创建一个新的状态对象,如果更新的对象层级较深,很容易弄成浅更新而出现bug,又需要引入immutable或immerjs等库
二、容易出性能问题
如果应用程序的状态树结构嵌套过深,会增加访问和更新状态的复杂度,使得性能降低。可考虑对状态进行规范化,将嵌套的结构拆分为扁平的结构
在组件树中,如果某个组件依赖的数据与其父组件传递的数据没有直接关系,但是每次父组件状态更新时都传递给子组件,会导致子组件频繁重新渲染,降低性能。可以通过 React Context 或者其他状态管理工具来避免不必要的数据传递。