React中如何在子组件提交表单时触发父组件的useEffect?
解决方案
方案1:状态提升(适合组件层级较浅的场景)
把加载Essay的逻辑和college状态抽到共同的父组件中,将刷新函数传递给AddEssay组件,提交表单后直接调用该函数重新拉取数据。
// 父组件 import { useState, useEffect } from 'react'; import EssayManager from './EssayManager'; import AddEssay from './AddEssay'; import { getEssaysByCollege } from './your-firestore-api'; function ParentComponent() { const [college, setCollege] = useState(''); const [essays, setEssays] = useState([]); // 加载Essay的核心函数 const loadEssays = async () => { if (!college) return; const fetchedEssays = await getEssaysByCollege(college); setEssays(fetchedEssays); }; // 初始加载+college变化时加载 useEffect(() => { loadEssays(); }, [college]); return ( <div> {/* 院校选择组件,更新college状态 */} <select value={college} onChange={(e) => setCollege(e.target.value)}> {/* 选项省略 */} </select> <EssayManager essays={essays} /> <AddEssay onEssayAdded={loadEssays} college={college} /> </div> ); } // AddEssay组件提交时调用传入的onEssayAdded function AddEssay({ onEssayAdded, college }) { const handleSubmit = async (formData) => { // 向Firestore新增Essay的逻辑 await addEssayToFirestore({ ...formData, college }); // 调用刷新函数 onEssayAdded(); }; return <form onSubmit={handleSubmit}> {/* 表单内容 */} </form>; } // EssayManager直接接收props里的essays渲染 function EssayManager({ essays }) { return ( <div> {essays.map(essay => <div key={essay.id}>{essay.title}</div>)} </div> ); }
方案2:React Context(适合组件层级较深的场景)
如果EssayManager和AddEssay层级嵌套较深,状态提升过于繁琐,可以用Context统一管理加载逻辑。
// 创建EssayContext.js import { createContext, useContext, useState, useEffect } from 'react'; import { getEssaysByCollege } from './your-firestore-api'; const EssayContext = createContext(); export function EssayProvider({ children }) { const [college, setCollege] = useState(''); const [essays, setEssays] = useState([]); const loadEssays = async () => { if (!college) return; const fetchedEssays = await getEssaysByCollege(college); setEssays(fetchedEssays); }; useEffect(() => { loadEssays(); }, [college]); return ( <EssayContext.Provider value={{ college, setCollege, loadEssays, essays }}> {children} </EssayContext.Provider> ); } export function useEssayContext() { return useContext(EssayContext); } // 在AddEssay中使用 function AddEssay() { const { loadEssays, college } = useEssayContext(); const handleSubmit = async (formData) => { await addEssayToFirestore({ ...formData, college }); loadEssays(); }; return <form onSubmit={handleSubmit}> {/* 表单内容 */} </form>; } // 在EssayManager中使用 function EssayManager() { const { essays } = useEssayContext(); return ( <div> {essays.map(essay => <div key={essay.id}>{essay.title}</div>)} </div> ); }
方案3:Firestore实时监听(推荐,无需手动触发刷新)
利用Firestore的onSnapshot监听集合变化,新增、修改、删除数据时会自动触发回调更新列表,彻底摆脱手动刷新的需求。
// EssayManager组件 import { useState, useEffect } from 'react'; import { db } from './firebase-config'; import { collection, query, where, onSnapshot } from 'firebase/firestore'; function EssayManager({ college }) { const [essays, setEssays] = useState([]); useEffect(() => { if (!college) return; // 创建查询:当前院校的Essay const q = query(collection(db, 'essays'), where('college', '==', college)); // 监听集合变化,实时更新 const unsubscribe = onSnapshot(q, (querySnapshot) => { const newEssays = []; querySnapshot.forEach((doc) => { newEssays.push({ id: doc.id, ...doc.data() }); }); setEssays(newEssays); }); // 组件卸载时取消监听 return () => unsubscribe(); }, [college]); return ( <div> {essays.map(essay => <div key={essay.id}>{essay.title}</div>)} </div> ); }
这种方式下,当AddEssay向Firestore提交新数据后,onSnapshot会自动捕捉到变化并更新essays状态,页面会实时刷新,不需要额外调用刷新函数。
内容的提问来源于stack exchange,提问作者tyty
相关产品推荐
相关产品推荐

