React子组件刷新后无法保留父组件传递的数据求助
问题原因与解决方法
核心问题
- 子组件state未同步props更新:子组件用
useState(props.data)初始化data状态,但useState的初始化仅在组件首次渲染时执行,后续父组件更新data并传递给子组件时,子组件的data状态不会自动同步。 - 表头计算逻辑未触发更新:计算表头的
useEffect依赖为空数组,仅执行一次,父组件刷新数据后不会重新计算表头。 - 空数据未做容错处理:直接访问
data[0],当data为空时会抛出错误,导致后续逻辑中断。
修复方案
方案1:直接使用props.data(推荐)
不需要在子组件中维护data状态,直接使用父组件传递的props.data,同时监听props.data的变化来更新表头:
const Child = (props) => { const [fields, setFields] = useState([]); const getHeaders = () => { // 先判断数据是否存在,避免报错 if (!props.data || props.data.length === 0) { setFields([]); return; } const fieldList = Object.keys(props.data[0]).map(field => ({ field })); setFields(fieldList); }; // 监听props.data变化,每次数据更新都重新计算表头 useEffect(() => { getHeaders(); }, [props.data]); return ( <div className="ag-theme-quartz" style={{ height: "100%" }}> <AgGridReact rowData={props.data} columnDefs={fields} /> </div> ); }; export default Child;
方案2:同步props.data到子组件state(需维护本地状态时用)
如果子组件需要对数据做本地修改,可通过useEffect监听props.data变化,同步更新子组件的data状态:
const Child = (props) => { const [data, setData] = useState(props.data || []); const [fields, setFields] = useState([]); const getHeaders = () => { if (!data || data.length === 0) { setFields([]); return; } const fieldList = Object.keys(data[0]).map(field => ({ field })); setFields(fieldList); }; // 同步父组件传递的data到子组件state useEffect(() => { setData(props.data); }, [props.data]); // 监听data变化,更新表头 useEffect(() => { getHeaders(); }, [data]); return ( <div className="ag-theme-quartz" style={{ height: "100%" }}> <AgGridReact rowData={data} columnDefs={fields} /> </div> ); }; export default Child;
父组件刷新功能补充(可选)
如果需要手动触发数据刷新,可给父组件添加刷新按钮:
const Parent = () => { const [data, setData] = useState([]); const getData = async () => { try { const res = await axios.get('url to data'); setData(res.data); } catch(error) { console.log(error); } }; useEffect(() => { getData(); }, []); return ( <div style={pageStyle}> <button onClick={getData}>刷新数据</button> <Child data={data}/> </div> ); }; export default Parent;
内容的提问来源于stack exchange,提问作者aghosh03
相关产品推荐
相关产品推荐

