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

React Hooks中如何通过子组件点击事件触发父组件重新渲染?——解决子组件删除后父组件重新获取数据失效问题

最优实现:子组件触发删除后父组件重新获取数据

你目前用虚拟计数器触发useEffect的方式虽然能跑通,但确实有点“绕”——它靠一个没有实际业务含义的状态来强制父组件重新请求数据,不仅读起来让人困惑,还可能带来不必要的组件重渲染。下面给你两种更符合React设计理念的最优方案,你可以根据项目规模选择:

方案一:传递刷新回调函数(父子组件简单交互首选)

这是最直接的方案,完全遵循React单向数据流的设计思想:父组件把“刷新数据”的逻辑封装成函数,传递给子组件;子组件完成删除操作后,调用这个函数通知父组件重新拉取数据。

修改后的代码示例

Parent.js

import { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
import Child from './Child';

function Parent() {
  const [myPetData, setMyPetData] = useState([]); // 初始化对应数据结构
  const token = localStorage.getItem("auth-token");

  // 抽离数据获取逻辑为独立函数,用useCallback缓存避免不必要的重渲染
  const fetchMyPetData = useCallback(() => {
    axios
      .get(`${BACK_PORT}/data/mypet`, {
        headers: { "auth-token": token }
      })
      .then(function (response) {
        setMyPetData(response?.data);
      })
      .catch(function (error) {
        console.error("获取宠物数据失败:", error);
      });
  }, [token]);

  // 组件挂载时首次获取数据
  useEffect(() => {
    fetchMyPetData();
  }, [fetchMyPetData]);

  return (
    <div>
      {/* 把刷新函数传递给子组件 */}
      <Child onDeleteFinish={fetchMyPetData} />
    </div>
  );
}

Child.js

import axios from 'axios';

function Child({ onDeleteFinish }) {
  const onDelete = () => {
    // 先执行删除请求(替换成你的实际删除接口)
    axios.delete(`${BACK_PORT}/data/mypet/[宠物ID]`, {
      headers: { "auth-token": localStorage.getItem("auth-token") }
    })
    .then(() => {
      // 删除成功后,调用父组件传递的刷新函数
      onDeleteFinish();
    })
    .catch(error => {
      console.error("删除失败:", error);
    });
  };

  return (
    <button onClick={onDelete}>删除宠物</button>
  );
}

方案优势

  • 代码逻辑清晰,一眼就能看懂“删除后要刷新数据”的关联关系
  • 没有冗余的状态变量,避免了无意义的组件重渲染
  • 完全符合React单向数据流的设计原则,维护成本低

方案二:使用Context/状态管理库(复杂场景首选)

如果你的项目存在多层组件共享数据、或者多个组件都需要触发数据刷新的场景,用React Context或者状态管理库(如Zustand、Redux)可以避免层层传递回调的麻烦,让数据逻辑更集中。

用React Context实现的示例

PetContext.js

import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import axios from 'axios';

const PetContext = createContext();

export function PetProvider({ children }) {
  const [myPetData, setMyPetData] = useState([]);
  const token = localStorage.getItem("auth-token");

  const fetchMyPetData = useCallback(() => {
    axios
      .get(`${BACK_PORT}/data/mypet`, {
        headers: { "auth-token": token }
      })
      .then(response => {
        setMyPetData(response?.data);
      })
      .catch(error => {
        console.error("获取宠物数据失败:", error);
      });
  }, [token]);

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

  return (
    <PetContext.Provider value={{ myPetData, fetchMyPetData }}>
      {children}
    </PetContext.Provider>
  );
}

// 自定义Hook,简化Context的调用
export function usePet() {
  return useContext(PetContext);
}

Parent.js

import { usePet } from './PetContext';
import Child from './Child';

function Parent() {
  const { myPetData } = usePet();
  return (
    <div>
      <Child />
    </div>
  );
}

Child.js

import axios from 'axios';
import { usePet } from './PetContext';

function Child() {
  const { fetchMyPetData } = usePet();

  const onDelete = () => {
    axios.delete(`${BACK_PORT}/data/mypet/[宠物ID]`, {
      headers: { "auth-token": localStorage.getItem("auth-token") }
    })
    .then(() => {
      fetchMyPetData();
    })
    .catch(error => {
      console.error("删除失败:", error);
    });
  };

  return (
    <button onClick={onDelete}>删除宠物</button>
  );
}

方案优势

  • 避免了props drilling(多层组件传递回调的麻烦)
  • 数据逻辑集中管理,多个组件可以直接调用刷新函数
  • 适合中大型项目,扩展性更强

总结

  • 若只是简单的父子组件交互,传递回调函数是最直接、最易维护的最优解;
  • 若项目存在跨组件数据共享或全局刷新需求,React Context/状态管理库能让代码结构更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 04:29:12