如何通过React高阶函数最大化可组合性 及connect函数的实现方法
connect函数的简易实现
你示例中的connect是Redux用于关联组件与全局Store的柯里化高阶API,核心逻辑是两次函数调用+高阶组件封装,以下是满足示例调用逻辑的可运行简化实现:
前置依赖
你需要先创建Redux上下文用于在组件树中传递Store实例:
import { createContext, useContext, useEffect, useState } from 'react'; // 全局Store上下文,需要在项目根组件用ReduxProvider传入store实例 const ReduxContext = createContext(); export const ReduxProvider = ReduxContext.Provider;
connect核心实现
function connect(mapStateToProps, mapDispatchToProps) { // 第一次调用返回高阶组件(HOC),接收业务组件作为参数 return function(WrappedComponent) { // 返回包装后的关联组件 return function ConnectedComponent(props) { const store = useContext(ReduxContext); if (!store) throw new Error('关联组件必须嵌套在ReduxProvider内部使用'); // 1. 把Store的state映射为要传给业务组件的props const stateProps = mapStateToProps ? mapStateToProps(store.getState(), props) : {}; // 2. 把dispatch映射为要传给业务组件的方法props let dispatchProps = {}; if (mapDispatchToProps) { if (typeof mapDispatchToProps === 'function') { // 支持函数格式的mapDispatchToProps dispatchProps = mapDispatchToProps(store.dispatch, props); } else { // 支持对象格式的action creator集合,自动绑定dispatch Object.keys(mapDispatchToProps).forEach(actionKey => { dispatchProps[actionKey] = (...args) => { store.dispatch(mapDispatchToProps[actionKey](...args)); }; }); } } // 3. 合并所有props:state映射结果、dispatch映射结果、组件自身传入的props const mergedProps = { ...stateProps, ...dispatchProps, ...props }; // 4. 监听Store变化,触发组件自动更新 const [, forceRender] = useState(0); useEffect(() => { const unsubscribe = store.subscribe(() => forceRender(prev => prev + 1)); return unsubscribe; }, [store]); // 5. 渲染原业务组件,传入合并后的props return <WrappedComponent {...mergedProps} />; }; }; }
调用示例(和你给出的写法完全对齐)
// 对应示例中的commentListSelector:定义要从Store取哪些字段传给组件 const commentListSelector = state => ({ commentList: state.comments.list, isLoading: state.comments.loading }); // 对应示例中的commentListActions:定义要传给组件的操作方法 const commentListActions = { fetchCommentList: () => ({ type: 'comments/fetchList' }), deleteComment: commentId => ({ type: 'comments/delete', payload: commentId }) }; // 和示例用法完全一致 const enhance = connect(commentListSelector, commentListActions); const ConnectedComment = enhance(CommentList);
补充说明
- 以上是简化实现,官方
react-redux库中的connect还做了大量性能优化,比如浅比较props变化避免不必要重渲染、映射结果缓存等 - 目前Redux官方更推荐用
useSelector、useDispatch两个Hook替代connect写法,语法更简洁,逻辑更直观
内容的提问来源于stack exchange,提问作者Chong Lip Phang
相关产品推荐
相关产品推荐

