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

React中useRef值在组件重渲染时意外重置的技术咨询

问题原因分析
  • 动态key导致组件实例重建:你给<AccordionSummary>设置了key={Math.random()},每次组件渲染时key都会生成新的随机值。React会判定这是一个全新组件,销毁旧实例并创建新的,因此useRef保存的状态会被重置为初始值0。
  • 错误的状态类型使用:AccordionSummary的expanded属性需要接收布尔值,你直接传入useRef对象,既不符合组件API要求,还会导致组件内部状态混乱,间接触发不必要的重渲染。
  • 子元素key不稳定:props.routeObj.map生成的<Box>用Math.random()当key,同样会导致子组件频繁重建,影响性能和状态稳定性。
解决办法
  1. 移除动态key:删掉<AccordionSummary>和<Box>上的key={Math.random()},改用数据中的唯一标识(比如stepObj的busNumber、mode组合)或索引作为key。
  2. 用useState管理展开状态:expanded是控制组件展开/收起的状态,需要触发重渲染,因此应该用useState代替useRef。
  3. 修正expanded属性传递:将布尔值状态正确传给AccordionSummary的expanded属性。

修正后的代码

import AccordionSummary from '@mui/material/AccordionSummary';
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
import DirectionsWalkIcon from '@mui/icons-material/DirectionsWalk';
import { Box } from "@mui/material";
import { useState } from 'react';

const RouteSummary = (props) => {
    // 用useState管理展开状态,初始值可根据需求调整
    const [expanded, setExpanded] = useState(false);

    const handleClick = () => {
        // 切换展开状态,若需计数可在此维护单独的状态
        setExpanded(prev => !prev);
        props.onClick();
    }

    return(
        <AccordionSummary 
            expanded={expanded} 
            onClick={handleClick}
            aria-controls="panel1a-content"
            sx={{width:"100%",display:"flex",paddingLeft:"2rem"}}
        >
            {props.routeObj.map((stepObj, index) => {
                // 生成稳定的key
                const key = stepObj.busNumber 
                    ? `${stepObj.mode}-${stepObj.busNumber}` 
                    : `${stepObj.mode}-${index}`;
                return (
                    <Box key={key} sx={{display:"flex"}}>
                        {stepObj.mode==="WALKING" ? <DirectionsWalkIcon/> : <DirectionsBusIcon/>} 
                        {stepObj.busNumber && (
                            <Box sx={{backgroundColor:"#FBCB0A",marginRight:"0.5rem",borderRadius:"5px",padding:"0.2rem"}}>
                                {stepObj.busNumber}
                            </Box>
                        )}
                    </Box>
                );
            }).reduce((prev, curr) => [prev, ' > ', curr])}
        </AccordionSummary>
    )
}

export default RouteSummary;

内容的提问来源于stack exchange,提问作者beeban

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:54:36