React项目替换过滤器为Core UI后useEffect未随数据变更触发问题
问题排查与修复方案
1. useEffect 依赖项语法错误
useEffect 的第二个参数只能传入一个依赖数组,你当前写了两个独立的数组:
// 错误写法 useEffect( () => {}, [dataFiltred], [dataSiteFiltred] )
这种写法下只有第一个数组[dataFiltred]会被识别为依赖,第二个数组直接被忽略。如果需要监听多个变量,要把所有依赖放在同一个数组内。
2. 未使用React状态存储响应式数据
你当前的dataFiltred、dataSiteFiltred都是普通JS变量,没有用useState声明。React的更新逻辑完全依赖状态变化,普通变量的修改不会被React感知,自然不会触发useEffect执行,也不会触发组件重渲染。
3. useEffect 内调用renderTableData无效
renderTableData是返回JSX的渲染函数,直接在useEffect里调用不会把生成的DOM挂载到页面上。你应该直接在组件的return语句中调用这个函数,不需要通过useEffect触发渲染。
4. 数组修改方式不符合响应式要求
就算你把数据改为状态,直接用push、直接赋值清空数组的写法也无法触发更新,因为React依赖引用变化判断是否更新,修改原数组引用不会变化,需要返回新数组。
修复后的参考代码
import { useState, useEffect } from 'react' // 组件内部代码 // 1. 用useState声明响应式数据 const [dataFiltred, setDataFiltred] = useState([]) const [dataSiteFiltred, setDataSiteFiltred] = useState([]) const renderTableData = () => { return ( <div className="selectTable"> <div className="ag-theme-alpine" style={{ height: "75vh", width: "110vw", // 原代码单位书写错误,wh改为vw alignContent: "center", alignItems: "center", alignSelf: "center", }} > <AgGridReact rowData={dataFiltred} rowHeight={rowHeight} rowStyle={{ textAlign: "center" }} > <AgGridColumn field="Pseudo"></AgGridColumn> <AgGridColumn field="Site"></AgGridColumn> <AgGridColumn field="Langue"></AgGridColumn> <AgGridColumn field="Actif_Inactif"></AgGridColumn> <AgGridColumn field="Date_Formation"></AgGridColumn> <AgGridColumn field="Formateur"></AgGridColumn> <AgGridColumn field="Nature_Formation"></AgGridColumn> <AgGridColumn field="Durée"></AgGridColumn> <AgGridColumn field="Action"></AgGridColumn> </AgGridReact> </div> </div> ); }; function onSiteChange(value, type) { if (type === "Site") { const newSiteFiltred = [] value.forEach((elem) => { rowData.forEach((data) => { if (data["Site"] === elem["value"]) { newSiteFiltred.push(data); } }); }); setDataSiteFiltred(newSiteFiltred) if (newSiteFiltred.length) { setDataFiltred([...newSiteFiltred]) } } } function updateTableData() { if (!dataFiltred.length) { setDataFiltred([...rowData]) } } // 首次加载初始化数据 useEffect(() => { updateTableData(); }, []) // 若有监听数据变化的逻辑可写在此处,无相关逻辑可直接删除该useEffect useEffect( () => { console.log("fired"); }, [dataFiltred, dataSiteFiltred] // 所有依赖放在同一个数组内 ); // 组件最后直接返回渲染内容即可 return <>{renderTableData()}</>
内容的提问来源于stack exchange,提问作者SEMER BEN SALEM
相关产品推荐
相关产品推荐

