You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:36:04