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

React非关联组件函数调用:如何在ProductModals中调用fetchData?

React子组件提交后刷新另一个子组件数据的解决方案

问题场景

现有React项目包含三个组件:viewProduct(父组件)、ProductTable、ProductModals。其中ProductTable内部有fetchData函数用于获取产品列表数据;ProductModals表单提交完成后,需要调用该fetchData函数刷新产品数据。

推荐两种可行实现方案,优先选择第一种状态提升方案:


方案一:状态提升+回调函数(推荐)

将产品数据和数据获取逻辑统一移到父组件viewProduct中,通过props传递数据给ProductTable,同时给ProductModals传递提交成功后的回调函数,触发数据刷新。

1. 修改父组件 viewProduct.js

import React, { useEffect, useState } from "react";
import ProductTable from "../../Components/Tables/Product/ProductTable";
import ProductModals from "../../Components/Modals/Product/ProductModals";
import axios from 'axios';

function viewProduct() {
  // 父组件维护产品数据状态
  const [productData, setProductData] = useState([]);

  // 统一的获取数据函数
  const fetchData = () => {
    axios
      .get("http://localhost:4000/api/products/product/viewAllProduct")
      .then((res) => {
        setProductData(res.data.data);
      })
      .catch(err => console.error('获取产品数据失败:', err));
  };

  // 初始化加载数据
  useEffect(() => {
    fetchData();
  }, []);

  // 提交成功后触发数据刷新的回调
  const handleSubmitSuccess = () => {
    fetchData();
  };

  return (
    <>
      <ProductModals onSubmitSuccess={handleSubmitSuccess} />
      <ProductTable data={productData} />
    </>
  );
}

export default viewProduct;

2. 修改 ProductTable.js

移除内部状态和fetchData,直接使用父组件传递的数据渲染:

import React from "react";

function ProductTable({ data }) {
  // 直接使用props传入的data进行渲染
  return (
    // 你的表格JSX代码,示例:
    <table>
      <thead>
        <tr>
          <th>产品名称</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        {data.map(product => (
          <tr key={product.id}>
            <td>{product.name}</td>
            <td>{product.price}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

export default ProductTable;

3. 修改 ProductModals.js

接收父组件传递的回调,在表单提交成功后调用:

import React, { useState } from "react";
import axios from 'axios';

function ProductModals({ onSubmitSuccess }) {
  const [formData, setFormData] = useState({ name: '', price: '' });

  const handleSubmit = (e) => {
    e.preventDefault();
    // 表单提交逻辑
    axios.post("http://localhost:4000/api/products/product/addProduct", formData)
      .then(() => {
        console.log('提交成功');
        // 触发父组件的刷新回调
        onSubmitSuccess();
        // 这里可以添加关闭模态框等后续操作
      })
      .catch(err => console.error('提交失败:', err));
  };

  return (
    // 你的模态框JSX代码,示例:
    <div className="modal">
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={formData.name}
          onChange={(e) => setFormData({...formData, name: e.target.value})}
          placeholder="产品名称"
        />
        <input
          type="number"
          value={formData.price}
          onChange={(e) => setFormData({...formData, price: e.target.value})}
          placeholder="价格"
        />
        <button type="submit">提交</button>
      </form>
    </div>
  );
}

export default ProductModals;

方案优势

  • 符合React单向数据流原则,数据统一由父组件管理,避免子组件间耦合
  • 子组件职责单一:ProductTable仅负责渲染,ProductModals仅负责表单提交
  • 代码易维护,后续修改数据逻辑只需在父组件调整

方案二:使用Ref调用子组件方法(不推荐)

通过React的ref获取ProductTable组件实例,直接调用其内部的fetchData方法。这种方式会破坏组件封装性,仅在特殊场景下使用。

1. 修改父组件 viewProduct.js

import React, { useRef } from "react";
import ProductTable from "../../Components/Tables/Product/ProductTable";
import ProductModals from "../../Components/Modals/Product/ProductModals";

function viewProduct() {
  const tableRef = useRef(null);

  const handleSubmitSuccess = () => {
    // 调用子组件的fetchData方法
    tableRef.current?.fetchData();
  };

  return (
    <>
      <ProductModals onSubmitSuccess={handleSubmitSuccess} />
      <ProductTable ref={tableRef} />
    </>
  );
}

export default viewProduct;

2. 修改 ProductTable.js

使用forwardRef和useImperativeHandle暴露内部方法:

import React, { useEffect, useState, forwardRef, useImperativeHandle } from "react";
import axios from 'axios';

const ProductTable = forwardRef((props, ref) => {
  const [data, setData] = useState([]);

  const fetchData = () => {
    axios
      .get("http://localhost:4000/api/products/product/viewAllProduct")
      .then((res) => {
        setData(res.data.data);
      })
      .catch(err => console.error('获取数据失败:', err));
  };

  useEffect(() => {
    fetchData();
  }, []);

  // 暴露fetchData给父组件的ref
  useImperativeHandle(ref, () => ({
    fetchData
  }));

  return (
    // 你的表格JSX代码
  );
});

export default ProductTable;

3. 修改 ProductModals.js

同方案一,接收onSubmitSuccess回调并在提交后调用即可。

方案缺点

  • 父组件依赖子组件内部实现,子组件修改方法名或逻辑时,父组件需同步调整
  • 破坏组件封装性,违反React组件设计原则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:31:02