如何同时连接React组件到Redux Store与Apollo Client并优化嵌套写法?
解决Apollo Client与Redux同时连接组件的嵌套问题
嘿,这种多层HOC嵌套的写法确实显得臃肿又难读,我之前在项目里也碰到过这个困扰。下面给你几个更简洁的方案,让你的组件代码清爽起来:
1. 使用Redux的compose函数组合HOC
Redux自带了compose工具函数,它能把多个高阶组件(HOC)按从右到左的顺序组合起来,完美替代嵌套写法。
示例代码:
import { connect } from 'react-redux'; import { graphql } from '@apollo/client/react/hoc'; import { compose } from 'redux'; import HelloForm from './HelloForm'; import { HELLO_QUERY } from './queries'; const mapStateToProps = (state) => ({ // 你的状态映射逻辑 }); const mapDispatchToProps = { // 你的dispatch映射逻辑 }; // 组合graphql和connect,顺序是先执行connect,再执行graphql const enhanceComponent = compose( graphql(HELLO_QUERY), connect(mapStateToProps, mapDispatchToProps) ); export default enhanceComponent(HelloForm);
这样写就把嵌套的HOC变成了线性的组合,可读性一下子提升了不少。如果你用的是lodash,也可以用flowRight(和compose功能完全一致)。
2. 用React Hooks替代HOC(推荐方案)
现在React生态更推荐用Hooks来处理状态和数据请求,完全不需要依赖HOC嵌套,代码更直观也更容易维护。
Apollo Client Hooks
Apollo提供了useQuery、useMutation等Hooks,直接在组件内部就能获取查询数据:
import { useQuery } from '@apollo/client'; import { HELLO_QUERY } from './queries'; function HelloForm() { const { data, loading, error } = useQuery(HELLO_QUERY); // 处理数据加载和错误状态 if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; // 组件逻辑... }
Redux Hooks
Redux的useSelector和useDispatch Hooks可以替代connect:
import { useSelector, useDispatch } from 'react-redux'; import { someAction } from './actions'; function HelloForm() { // 获取Redux状态 const someState = useSelector(state => state.someSlice); // 获取dispatch函数 const dispatch = useDispatch(); // 触发action const handleClick = () => dispatch(someAction()); // 组件逻辑... }
把两者结合起来,你的组件直接导出就行,完全不需要任何HOC包裹:
import { useQuery } from '@apollo/client'; import { useSelector, useDispatch } from 'react-redux'; import { HELLO_QUERY } from './queries'; import { someAction } from './actions'; function HelloForm() { const { data, loading, error } = useQuery(HELLO_QUERY); const someState = useSelector(state => state.someSlice); const dispatch = useDispatch(); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; return ( <div> <p>{data?.hello}</p> <p>Redux State: {someState}</p> <button onClick={() => dispatch(someAction())}>Trigger Action</button> </div> ); } export default HelloForm;
这种方式不仅消除了HOC嵌套,还让数据和状态的来源更清晰,是目前最推荐的写法。
总结
- 如果你的项目还在使用HOC风格的代码,
compose函数是快速简化嵌套的好方法; - 如果你可以升级到Hooks写法,完全抛弃HOC会让代码更简洁、更易维护,这也是React社区的主流趋势。
内容的提问来源于stack exchange,提问作者Mohamed Taboubi
相关产品推荐
相关产品推荐

