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

React子组件点击按钮如何重新获取数据?基于HOC与React-Router-DOM

解决方案:子组件触发HOC重新获取数据

核心结论

可以通过React-Router-DOM实现,但更推荐直接将刷新方法传递给子组件的方案——这种方式更简洁高效,且能完全保证数据同步。


方案一:通过React-Router-DOM触发路由刷新

利用路由参数变化触发组件重新渲染,从而让HOC再次执行数据获取逻辑:

步骤1:修改HOC,引入路由参数管理

import { useSearchParams } from 'react-router-dom';

export const HOC = ({ Component }) => {
  const [searchParams, setSearchParams] = useSearchParams();
  
  const fetchData = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const data = {
          message: 'Data fetched successfully' + Math.floor(Math.random() * 100),
        };
        resolve(data);
      }, 2000);
    });
  };

  // 传递刷新函数给子组件:通过添加随机查询参数触发路由更新
  const refresh = () => {
    setSearchParams({ t: Date.now().toString() });
  };

  return (
    <div>
      <If condition={fetchData()}>
        <Fallback>Loading data ...</Fallback>
        <Then>
          {(data) => (
            <>
              <span>parent component your data:{JSON.stringify(data)}</span>
              <Component data={data} refresh={refresh} />
            </>
          )}
        </Then>
        <Else>{(error) => <span>Failed to load data: {error?.message}</span>}</Else>
      </If>
    </div>
  );
};

步骤2:子组件调用刷新函数

在子组件(比如App)中,给按钮绑定refresh方法:

export default function App({ data, refresh }) {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <p>Child component data: {data?.message}</p>
      <button onClick={refresh}>重新获取数据</button>
    </div>
  );
}

原理:添加随机查询参数后,React Router会识别路由变化,重新渲染HOC组件,进而重新执行fetchData。


方案二:直接传递刷新方法给子组件(推荐)

你的担心其实可以通过在HOC中维护数据状态来解决,这样父组件和子组件的数据完全同步:

步骤1:重构HOC,添加状态管理

import { useState, useEffect } from 'react';

export const HOC = ({ Component }) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const fetchData = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const data = {
          message: 'Data fetched successfully' + Math.floor(Math.random() * 100),
        };
        resolve(data);
      }, 2000);
    });
  };

  // 封装数据加载逻辑
  const loadData = async () => {
    setLoading(true);
    try {
      const res = await fetchData();
      setData(res);
      setError(null);
    } catch (err) {
      setError(err as Error);
    } finally {
      setLoading(false);
    }
  };

  // 组件挂载时加载数据
  useEffect(() => {
    loadData();
  }, []);

  return (
    <div>
      {loading && <span>Loading data ...</span>}
      {error && <span>Failed to load data: {error.message}</span>}
      {data && (
        <>
          <span>parent component your data:{JSON.stringify(data)}</span>
          <Component data={data} refreshData={loadData} />
        </>
      )}
    </div>
  );
};

步骤2:子组件触发刷新

export default function App({ data, refreshData }) {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <p>Child component data: {data?.message}</p>
      <button onClick={refreshData}>重新获取数据</button>
    </div>
  );
}

优势:

  • 完全避免路由参数的额外开销,性能更优
  • 数据状态由HOC统一管理,父/子组件数据绝对同步
  • 代码逻辑更清晰,符合React状态管理的常规实践

方案对比

方案优点缺点
路由刷新无需修改HOC的状态逻辑增加路由冗余参数,路由变化可能触发其他副作用
传递刷新方法性能优、数据同步可靠、逻辑清晰需要重构HOC的状态管理

优先选择传递刷新方法的方案,这是React组件间通信的标准做法,能彻底解决你的数据同步顾虑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:53:10