使用recompose的withStateHandlers与TypeScript时,类型是否泄漏到组件?
我来帮你理清楚这个问题~
首先要明确:你目前的操作其实没有错误,这是withStateHandlers这个高阶组件(HOC)的预期行为,recompose的类型定义也不存在缺陷,只是可能你对它的用法逻辑有点误解。
为什么必须让SFC的props匹配HOC“泄漏”的内容?
withStateHandlers的核心作用就是给被包装的组件注入内部状态和对应的状态更新方法——它会把你定义的状态(比如isEditing)和处理函数(比如toggleEditing)作为props传递给你的无状态组件(SFC)。所以你的SFC必须声明这些props是它的输入,TypeScript才会认可这种类型匹配,这是类型安全的必要保障,并不是所谓的“泄漏”。
如何让SFC更“纯净”?
如果你的需求是让SFC只专注于展示逻辑,不想让它接收状态相关的props,可以把组件拆分成纯展示组件和容器组件两部分:
- 纯展示组件只接收业务相关的props(比如
className)和触发交互的回调(比如onClick),完全不关心状态逻辑; - 用
withStateHandlers包装这个展示组件,把状态管理逻辑放在HOC里,自动注入状态和更新方法。
举个TypeScript的示例:
// 纯展示组件:只负责渲染,不关心状态来源 interface IDisplayProps { className?: string; isEditing: boolean; onClick: () => void; } const DisplayButton: React.SFC<IDisplayProps> = ({ className, isEditing, onClick }) => ( <button className={className} onClick={onClick}> {isEditing ? '完成编辑' : '开始编辑'} </button> ); // 用withStateHandlers包装,注入状态和逻辑 import { withStateHandlers } from 'recompose'; const MyComponent = withStateHandlers( // 初始状态 { isEditing: false }, // 状态处理函数 { toggleEditing: () => () => ({ isEditing: prev => !prev }) } )(DisplayButton);
这样当你使用MyComponent时,只需要传递className即可,isEditing和toggleEditing的逻辑完全被HOC封装起来,SFC也保持了纯净性。
关于类型定义的补充
如果你不想拆分组件,也可以用TypeScript的工具类型合并props,减少重复声明:
import { withStateHandlers } from 'recompose'; // 定义HOC的状态和处理函数类型 type ComponentState = { isEditing: boolean }; type ComponentHandlers = { toggleEditing: () => void }; // 合并原始props和HOC注入的props type IProps = { className?: string } & ComponentState & ComponentHandlers; const MyComponent: React.SFC<IProps> = ({ className, isEditing, toggleEditing }) => ( <button className={className} onClick={toggleEditing}> {isEditing ? '保存' : '编辑'} </button> ); // 包装时指定类型参数,确保类型匹配 const WrappedComponent = withStateHandlers<ComponentState, ComponentHandlers, {}>( { isEditing: false }, { toggleEditing: () => () => ({ isEditing: prev => !prev }) } )(MyComponent);
总结
你遇到的情况是withStateHandlers的正常工作逻辑,不是操作错误也不是类型缺陷。如果觉得props过于繁杂,拆分展示组件和容器组件是更符合React设计思想的解决方案,能让代码职责更清晰。
内容的提问来源于stack exchange,提问作者Matt Greer
相关产品推荐
相关产品推荐

