You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:44:35