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

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;

问题分析

  1. Props覆盖问题:代码中disabled={nodeDisabled}写在...props.treeItemProps之前,若treeItemProps中包含disabled属性,会直接覆盖自定义的禁用状态值,导致状态更新不生效。
  2. 组件渲染触发机制:当父组件传递的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:30:43