React中如何在子组件A请求完成后触发同级子组件B重新渲染
跨组件触发更新的高效实现方案
你目前的场景是组件A提交数据成功后需要触发组件B重新拉取最新数据,除了dummy状态变量的方案,还有以下几种更合理高效的实现方式,可根据你的项目规模和组件层级选择:
方案1:状态提升(无额外依赖,优先推荐)
这是React原生最轻量化的方案,适合A、B两个组件为同级、父组件层级不远的场景:
- 把组件B内部的
payments状态和fetchPayments方法提升到A、B的公共父组件中 - 父组件将
fetchPayments方法通过prop传递给组件A,将payments数据通过prop传递给组件B - 组件A提交请求成功后直接调用传入的
fetchPayments方法即可自动更新B的展示内容
代码示例
公共父组件代码
import React, { useState, useEffect } from 'react' import ComponentA from './ComponentA' import ComponentB from './ComponentB' const Home = () => { const [payments, setPayments] = useState([]) const fetchPayments = async () => { const res = await axios.get(`http://localhost:4000/paymentspending`) setPayments(res.data) } // 首次加载拉取数据 useEffect(() => { fetchPayments() }, []) return ( <div> <ComponentA fetchPayments={fetchPayments} /> <ComponentB payments={payments} fetchPayments={fetchPayments} /> </div> ) } export default Home
调整后的组件A代码
// 组件A接收父组件传入的fetchPayments方法 const ComponentA = ({ fetchPayments }) => { // 原有状态定义vendor、amount省略 const onSubmit = async (event) => { event.preventDefault(); if (vendor === "" || amount === "") return const res = await axios.post(`http://localhost:4000/newpayment`, { vendor, amount, }); // 校验请求成功后调用拉取方法 if (res.status === 200) { fetchPayments() } setVendor(""); setAmount(""); }; // 原有渲染逻辑省略 }
调整后的组件B代码
import React from "react"; import axios from "axios"; // 组件B接收父组件传入的payments数据和fetchPayments方法 const ComponentB= ({ payments, fetchPayments }) => { const onClick = async (id) => { await axios.post(`http://localhost:4000/markpaid`, { id }); fetchPayments(); }; const renderedPayments = Object.values(payments).map((payment) => { return ( <div className="card" style={{ width: "100%", marginBottom: "20px" }} key={payment.id} > <div className="card-body"> <h4>{payment.vendor}</h4> <h5>{payment.amount}</h5> <button className="btn btn-success" onClick={() => onClick(payment.id)} > Mark as Paid </button> </div> </div> ); }); return <div className="d-flex flex-row flex-wrap">{renderedPayments}</div>; }; export default ComponentB;
方案2:Context 上下文
如果A、B组件层级很深,逐层传prop过于麻烦,可以用React自带的Context实现跨层级传递方法:
- 创建支付相关的Context,把
fetchPayments方法放入Context的Provider中,包裹住主页所有组件 - 组件A和B都通过useContext消费Context,直接调用
fetchPayments方法即可
方案3:全局状态管理
如果你的项目已经引入了Zustand、Redux、Jotai等状态管理库,可以直接把支付数据存在全局store中:
- 组件A提交成功后触发store的更新方法拉取最新数据
- 组件B订阅store中的payments数据,数据变化时自动重渲染
这种方案适合中大型项目,跨页面、跨多层级组件共享数据的场景。
方案4:自定义事件总线(不优先推荐)
如果组件耦合度非常低,不想用以上方案,可以用浏览器自定义事件实现:
- 组件B挂载时监听自定义的
paymentUpdate事件,触发时调用fetchPayments - 组件A提交成功后dispatch一个
paymentUpdate事件即可
注意要在组件卸载时移除事件监听,避免内存泄漏
内容的提问来源于stack exchange,提问作者something papaya
相关产品推荐
相关产品推荐

