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

React扩展函数式组件的替代方案:如何复用含useEffect的公共逻辑

解决方案

方案1:自定义Hook(推荐优先级最高)

React 自定义Hook的设计初衷就是复用组件状态逻辑,完全匹配你的需求,不需要组件继承,也无需重复编写useEffect逻辑。

步骤1:封装自定义Hook

import { useSelector } from 'react-redux';
import { useEffect } from 'react';

// 全局只需要定义一次该Hook
const useInitProdData = (AHigherOrderComponent) => {
  // 直接从Redux Store读取需要的参数,无需通过props透传
  const country = useSelector(state => state.country);
  const prodData = useSelector(state => state.prodData);
  const index = useSelector(state => state.index);

  useEffect(() => {
    // 增加数据存在性守卫,避免未加载时抛出错误
    if (!country || !prodData?.[index]) return;

    const [, code] = country.split('-');
    const { sampleData, period, indication } = prodData[index];

    AHigherOrderComponent(someReadDataFunction(code, sampleData));
    AHigherOrderComponent(someReadDataFunction(code, period));
    AHigherOrderComponent(someReadDataFunction(code, indication));
  }, [country, prodData, index, AHigherOrderComponent]);
};

步骤2:嵌套组件内调用

在三个嵌套组件中只需要一行代码即可调用,无需重复写逻辑:

// 以NestedComponent1为例,其余两个组件写法完全一致
import { useInitProdData } from 'xxx';

const NestedComponent1 = ({ highOrder: { AHigherOrderComponent } }) => {
  // 直接调用自定义Hook,加载时自动执行数据读取逻辑
  useInitProdData(AHigherOrderComponent);

  // 原有组件逻辑保持不变
  return <div>{/* 原有内容 */}</div>;
};

export default withHighOrder(NestedComponent1);

该方案优势:

  • 逻辑仅编写一次,所有嵌套组件直接复用
  • 自动获取Redux Store最新值,无需处理props传递链路
  • 依赖项声明完整,不存在闭包陷阱

方案2:无渲染逻辑组件(适配你原有组件思路)

如果你更倾向用组件形式实现,可编写不渲染任何UI的纯逻辑组件,直接嵌入嵌套组件的JSX结构即可,不需要在useEffect中调用组件。

步骤1:封装逻辑组件

import { useSelector } from 'react-redux';
import { useEffect } from 'react';

const ProdDataInit = ({ AHigherOrderComponent }) => {
  const country = useSelector(state => state.country);
  const prodData = useSelector(state => state.prodData);
  const index = useSelector(state => state.index);

  useEffect(() => {
    if (!country || !prodData?.[index]) return;

    const [, code] = country.split('-');
    const { sampleData, period, indication } = prodData[index];

    AHigherOrderComponent(someReadDataFunction(code, sampleData));
    AHigherOrderComponent(someReadDataFunction(code, period));
    AHigherOrderComponent(someReadDataFunction(code, indication));
  }, [country, prodData, index, AHigherOrderComponent]);

  // 不输出任何UI内容
  return null;
};

export default ProdDataInit;

步骤2:嵌套组件内引入

// 以NestedComponent1为例
import ProdDataInit from 'xxx';

const NestedComponent1 = ({ highOrder: { AHigherOrderComponent } }) => {
  return (
    <div>
      {/* 直接插入逻辑组件,加载时自动触发useEffect */}
      <ProdDataInit AHigherOrderComponent={AHigherOrderComponent} />
      {/* 原有组件内容保持不变 */}
    </div>
  );
};

export default withHighOrder(NestedComponent1);

补充注意:你原有代码存在两处问题,示例中已修正:

  1. 错误的重复赋值语法 const sampleData = prodData[index].sampleData = sampleData; 改为直接解构取值
  2. 原useEffect依赖项为空数组,会导致闭包问题,已补充完整依赖项

内容的提问来源于stack exchange,提问作者stacky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:15:05