React/Next中useEffect被重复调用两次,如何避免reinitializePage修改后二次触发?
方案1:通过ref追踪上下文变化,过滤无效触发
使用useRef存储上一次的corporateContext值,仅在reinitializePage为true或corporateContext真实变更时执行业务逻辑,即可排除reinitializePage从true改为false时的无效触发:
const [reinitializePage, setReinitializePage] = useState(true); // 存储上一次的corporateContext用于比对变化 const prevCorporateContextRef = useRef(corporateContext); useEffect(() => { const isContextUpdated = prevCorporateContextRef.current !== corporateContext; if (reinitializePage === true || isContextUpdated) { (async () => { ... })(); setReinitializePage(false); // 更新存储的上下文值 prevCorporateContextRef.current = corporateContext; } }, [reinitializePage, corporateContext]);
该方案无需拆分原有逻辑,同时保留两个触发场景的独立性,也支持后续手动将reinitializePage设为true触发重新初始化。
方案2:拆分独立useEffect(职责更清晰)
如果两个触发场景的后续维护逻辑可能存在差异,可以抽离公共业务函数,拆分两个useEffect分别处理不同触发场景,通过ref标记避免初始化阶段重复执行:
const [reinitializePage, setReinitializePage] = useState(true); const initFinishedRef = useRef(false); // 抽离公共业务逻辑 const handlePageUpdate = async () => { // 原有异步业务逻辑 }; // 处理初始化/重新初始化场景 useEffect(() => { if (reinitializePage) { handlePageUpdate(); setReinitializePage(false); initFinishedRef.current = true; } }, [reinitializePage]); // 处理上下文变更场景 useEffect(() => { // 初始化阶段已执行过逻辑,跳过首次触发 if (!initFinishedRef.current) return; handlePageUpdate(); }, [corporateContext]);
内容的提问来源于stack exchange,提问作者Denis2310
相关产品推荐
相关产品推荐

