React子组件向兄弟组件传数组时数据滞后问题求助
问题描述
我开发的Footer组件会创建reminders数组,希望通过共同父组件RmList将该数组传递给兄弟组件Body,实现点击Footer按钮时Body实时打印最新数组。但目前每次点击后,Body打印的数组总比Footer少一个元素。我曾尝试将setReminders([newReminder, ...reminders])改为函数式更新setReminders(prevRems => [...prevRems, newReminder]),但因无法传递prevRems给父组件,问题仍未解决,恳请帮助。
原Footer组件代码
import './style.css' function Footer({ linkToFooter }){ const [reminder, setReminder] = useState(""); const [reminders, setReminders] = useState([]); const submitThis = (e) => { e.preventDefault(); if (reminder){ let newReminder = { reminder: reminder, complete: false, }; setReminders(prevRems => [...prevRems, newReminder]) setReminder(''); } else { setReminder("oops there's a problem"); } }; useEffect( () => { localStorage.setItem('reminders', JSON.stringify(reminders)); }, [reminders] ); console.log(reminders, "from Footer"); return( <div className="rm-list-footer"> <form onSubmit={submitThis}> <input id='newReminder' type='text' value={reminder} onChange={(e) => setReminder(e.target.value)} /> <button onClick={() => linkToFooter(reminders)} type='submit'>+</button> </form> </div> ) } export default Footer;
原父组件RmList代码
import Header from "./Header"; import Footer from "./Footer"; import Body from "./Body"; function RmList() { const [reminders, setReminders] = useState([]) return( <div className="rm-list"> <Header></Header> <Body reminders={reminders}></Body> <Footer linkToFooter={setReminders}></Footer> </div> ); } export default RmList;
原Body组件代码
import React from "react"; function Body({reminders}) { console.log(reminders, "from Body"); return( <div className="rm-list-body"></div> ); } export default Body;
问题原因与解决方案
问题核心是Footer组件同时维护了自己的reminders状态,且传递给父组件的是更新前的旧值:React状态更新是异步的,点击按钮时linkToFooter(reminders)里的reminders还没完成更新,导致父组件拿到的永远是少一个元素的数组。
解决思路:将状态统一放到父组件RmList中维护,Footer不再单独存储reminders,所有组件共享同一状态源。
修改后的Footer组件
import './style.css' import { useState, useEffect } from 'react'; function Footer({ reminders, addReminder }){ const [reminder, setReminder] = useState(""); const submitThis = (e) => { e.preventDefault(); if (reminder){ const newReminder = { reminder: reminder, complete: false, }; addReminder(newReminder); setReminder(''); } else { setReminder("oops there's a problem"); } }; useEffect( () => { localStorage.setItem('reminders', JSON.stringify(reminders)); }, [reminders] ); console.log(reminders, "from Footer"); return( <div className="rm-list-footer"> <form onSubmit={submitThis}> <input id='newReminder' type='text' value={reminder} onChange={(e) => setReminder(e.target.value)} /> <button type='submit'>+</button> </form> </div> ) } export default Footer;
修改后的父组件RmList
import Header from "./Header"; import Footer from "./Footer"; import Body from "./Body"; import { useState, useEffect } from 'react'; function RmList() { const [reminders, setReminders] = useState([]); const addReminder = (newReminder) => { setReminders(prev => [...prev, newReminder]); }; // 页面加载时从localStorage恢复数据(可选优化) useEffect(() => { const savedReminders = localStorage.getItem('reminders'); if (savedReminders) setReminders(JSON.parse(savedReminders)); }, []); return( <div className="rm-list"> <Header></Header> <Body reminders={reminders}></Body> <Footer reminders={reminders} addReminder={addReminder}></Footer> </div> ); } export default RmList;
Body组件无需修改
import React from "react"; function Body({reminders}) { console.log(reminders, "from Body"); return( <div className="rm-list-body"></div> ); } export default Body;
内容的提问来源于stack exchange,提问作者barbarbytes
相关产品推荐
相关产品推荐

