MUI TreeView TreeItem禁用状态切换后无法即时更新的问题
MUI TreeView TreeItem禁用状态切换不即时生效问题
问题现象
使用递归函数渲染TreeItem的MUI TreeView组件,切换所有TreeItem的禁用状态后,组件不会立即更新禁用状态,需点击页面其他区域才会生效。其中toggle按钮从第二次点击起行为符合预期,但另外两个按钮始终存在该问题。
相关代码
const Tree = (props: Props) => { const handleToggle = (event: React.SyntheticEvent, nodeIds: string[]) => { setExpanded(nodeIds); }; const renderTreeItems = ( node: MyNode, nodeDisabled: boolean, ) => { return ( <StyledTreeItemRoot key={node.id} nodeId={'' + node.id} label={ <Box sx={{ display: 'flex', alignItems: 'center', p: 0.5, pr: 0 }}> <Typography variant='body2' > {node.title} </Typography> </Box> } disabled={nodeDisabled} {...props.treeItemProps} > {Array.isArray(node.children) ? node.children.map((node) => renderTreeItems(node, nodeDisabled)) : null} </StyledTreeItemRoot> ); }; return ( <TreeView expanded={expanded} selected={props.selectedNodeId} onNodeSelect={(_event: React.SyntheticEvent, nodeId: string) => { props.onSelect(nodeId); }} onNodeToggle={handleToggle} {...props.treeViewProps} > {props.tree.map((item) => renderTreeItems(item, props.treeDisabled ?? false), )} </TreeView> ); }; export default Tree;
问题分析
- Props覆盖问题:代码中
disabled={nodeDisabled}写在...props.treeItemProps之前,若treeItemProps中包含disabled属性,会直接覆盖自定义的禁用状态值,导致状态更新不生效。 - 组件渲染触发机制:当父组件传递的
treeDisabled变化时,TreeItem的props变化未被正确识别,无法触发即时重渲染;部分按钮(如toggle)因同时触发了TreeView的展开/折叠状态更新,间接触发了组件重渲染,所以第二次点击后正常。
解决方案
1. 调整Props顺序,确保禁用状态优先级
将disabled={nodeDisabled}移到...props.treeItemProps之后,避免自定义状态被覆盖:
<StyledTreeItemRoot key={node.id} nodeId={'' + node.id} label={ <Box sx={{ display: 'flex', alignItems: 'center', p: 0.5, pr: 0 }}> <Typography variant='body2'> {node.title} </Typography> </Box> } {...props.treeItemProps} disabled={nodeDisabled} // 移至props展开后,确保优先级 >
2. 强制TreeItem重渲染
若调整props顺序后仍无效,可通过修改key值强制组件重新挂载,确保状态即时更新:
<StyledTreeItemRoot key={`${node.id}-${nodeDisabled}`} // 将禁用状态纳入key,状态变化时触发重渲染 nodeId={'' + node.id} label={/* ... */} {...props.treeItemProps} disabled={nodeDisabled} >
3. 检查父组件状态管理
确保父组件中treeDisabled是通过useState管理的稳定状态,避免传递临时变量或不稳定引用,确保状态变化能正确触发Tree组件的重渲染。
内容的提问来源于stack exchange,提问作者Mangs
相关产品推荐
相关产品推荐

