Material UI Table组件父组件props变化时未重新渲染问题求助
问题根因分析
排查以下几个常见触发点即可定位问题:
- 父组件监听
change的useEffect依赖项缺失,触发闭包陷阱 - 若子组件
InlineTable被React.memo包裹,引用类型props修改时未更新引用导致浅比较不通过 Autocomplete自带的autoFocus属性仅在组件初始挂载时生效,prop更新时不会重新触发聚焦,容易被误判为组件未重新渲染
正确解决方案
1. 修复父组件useEffect依赖问题
给监听change的useEffect补充focusedField依赖,同时调整判断逻辑为互斥分支,避免连续误触发状态更新:
const [focusedField,setFocusedField] = useState ('insuranceType') useEffect(() => { const keypress = e => { if(e.key == "Enter" ){ setChange(true) } }; window.addEventListener("keypress", keypress); return () => { window.removeEventListener("keypress", keypress); }; }, []); React.useEffect(()=>{ if(change){ if(focusedField == "insuranceType" ){ setFocusedField("tests") } else if(focusedField == "tests" ){ setFocusedField("calculateTestCosts") } else if(focusedField == "calculateTestCosts" ){ setFocusedField("nationalId") } else if(focusedField == "nationalId" ){ setFocusedField("patientName") } else if(focusedField == "patientName" ){ setFocusedField("patientSurname") } setChange(false) } },[change, focusedField]) // 补充focusedField依赖
2. 规范引用类型状态的更新写法
所有对象、数组类型的状态修改都要返回新的引用,避免React.memo浅比较判断为无变化跳过渲染,以修改tableContent为例:
// 错误写法:直接修改原数组引用 tableContent[index].codeName = newValue setTableContent(tableContent) // 正确写法:返回全新的数组+对象引用 setTableContent(prev => { const newArr = [...prev] newArr[index] = {...newArr[index], codeName: newValue} return newArr })
如果子组件接收了自定义的函数类型props,需要用useCallback包裹回调函数保证引用稳定。
3. 手动控制聚焦替代autoFocus属性
不用销毁重建组件,用ref手动触发输入框聚焦即可实现需求:
// 子组件代码 const inputRefs = useRef([]) // 监听focusedField变化手动触发聚焦 React.useEffect(()=>{ if(focusedField === "tests" && inputRefs.current[0]){ inputRefs.current[0].focus() } },[focusedField]) return ( <TableContainer> <TableBody> {tableContent.map((row,index) => ( <TableCell style={{width : "20%" , paddingRight : 1 , paddingLeft : 0}}> <Autocomplete id="tests" name="tests" options={["1" , "2"]} value={row?.codeName} onChange={(e,newValue)=>handleOnChange(newValue,`codeName`,index)} renderInput={(params) => <TextField {...params} label={<p style={{fontSize : "10px"}}>کد-نام تست</p>} inputRef={el => inputRefs.current[index] = el} // 绑定ref inputProps={{ ...params.inputProps, tabIndex: 2}} />} /></TableCell> ))} </TableBody> </TableContainer> )
内容的提问来源于stack exchange,提问作者m.mahdi_rasouli
相关产品推荐
相关产品推荐

