使用Recompose实现的React HOC无法处理默认props问题
嘿,我刚好之前踩过Recompose处理默认props的坑!你遇到的问题本质是withHandlers创建函数时依赖的props还没拿到默认值——如果默认props是在HOC外层设置的,Recompose的高阶组件在初始化withHandlers的时候,这些默认值还没被注入进去,导致onCallback是undefined,自然会报错。
问题根源
Recompose的withHandlers是在组件初始化阶段,基于当时传入的props来创建处理函数的。如果你是在HOC包裹后的组件上设置defaultProps,这个默认值是在组件渲染时才会被应用的,晚于withHandlers的初始化时机,所以handleSave里捕获的onCallback还是undefined。
正确的解决方式
把默认props的注入放到compose链的最前面,用withProps来提供默认值,确保withHandlers创建函数时能拿到合法的onCallback:
import React from 'react' import { withStateHandlers, withHandlers, compose, withProps } from 'recompose' const editableRow = () => compose( // 第一步:先注入默认props,确保后续所有环节都能拿到 withProps((props) => ({ // 如果外部没传onCallback,就用一个空函数兜底 onCallback: props.onCallback || (() => {}) })), withStateHandlers( { isEditing: false, editingId: null }, { toggleEditing: ({ isEditing, editingId }) => (id) => ({ isEditing: !isEditing, editingId: id }) } ), withHandlers({ handleSave: ({ editingId, onCallback, toggleEditing }) => () => { // 现在可以安全调用onCallback了,不会有undefined的问题 onCallback(editingId); toggleEditing(null); } }) )(WrappedComponent => (props) => <WrappedComponent {...props} />);
额外注意点
别再用这种方式设置默认props了:
const Enhanced = editableRow()(MyComponent); Enhanced.defaultProps = { onCallback: () => {} }; // 这种方式会失效!
因为withHandlers已经在初始化时捕获了没有默认值的props,后续渲染时的默认props无法回溯修改已经创建好的handleSave函数。
如果你的WrappedComponent本身已经设置了defaultProps,那可以不用在HOC里重复处理,但如果是HOC层面需要兜底,withProps是最可靠的方式。
内容的提问来源于stack exchange,提问作者Istvan Orban
相关产品推荐
相关产品推荐

