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

