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

React中如何使用Ref获取节点及创建Ref数组处理Tree勾选?

Fixing the "Always Gets Last Node" Issue with React Refs for Tree Nodes

Hey Javier, let's break down why you're only getting the last node in your onCheck callback and fix this properly!

What's Going Wrong Right Now

The core issue is simple: you're assigning all your TreeNode components to a single ref (this.myRef). Every time your loop function renders a new node, it overwrites the previous ref value. By the time the render finishes, this.myRef.current will only point to the last rendered node—no matter which node you check.

Step-by-Step Solution

We need to store a unique ref for each TreeNode instead of a single one. Here's how to implement this:

1. Initialize a Ref Collection

First, create an object in your component to hold references to every TreeNode. For class components, add this to your constructor:

constructor(props) {
  super(props);
  this.nodeRefs = {}; // Use each TreeNode's unique key as the object key
}

2. Assign Refs to Each TreeNode

Instead of using a single ref, use a ref callback to store each node in your nodeRefs object. Update your loop function like this:

const loop = (data) => {
  return data.map((item) => {
    if (item.children && item.children.length) {
      return (
        <TreeNode
          ref={(node) => (this.nodeRefs[item.key] = node)} // Store ref by item's unique key
          title={item.name}
          key={item.key}
          checked={item.checked}
        >
          {loop(item.children)}
        </TreeNode>
      );
    }
    return (
      <TreeNode
        ref={(node) => (this.nodeRefs[item.key] = node)} // Same approach for leaf nodes
        title={item.name}
        key={item.key}
        isLeaf={item.isLeaf}
        checked={item.checked}
      />
    );
  });
};

3. Fetch the Correct Node in onCheck

Now in your onCheck callback, use the event object to get the key of the node that was just checked/unchecked, then pull the corresponding ref from your nodeRefs object:

onCheck = (checkedKeys, event) => {
  // Get the unique key of the node that triggered the event
  const currentNodeKey = event.node.key;
  // Fetch the exact node ref from our collection
  const currentNode = this.nodeRefs[currentNodeKey];

  if (!currentNode) return;

  console.log("Current checked node:", currentNode);

  // Now you can use DOM APIs to modify related nodes
  // Example: Update parent node's checked state
  const parentNode = currentNode.parentNode;
  if (parentNode) {
    const parentCheckbox = parentNode.querySelector(".ant-tree-checkbox-input");
    if (parentCheckbox) {
      parentCheckbox.checked = event.checked;
      // Trigger a change event so React picks up the update
      parentCheckbox.dispatchEvent(new Event("change"));
    }
  }

  // Example: Update all child nodes' checked state
  const childNodes = currentNode.querySelectorAll(".ant-tree-node");
  childNodes.forEach((child) => {
    const childCheckbox = child.querySelector(".ant-tree-checkbox-input");
    if (childCheckbox) {
      childCheckbox.checked = event.checked;
      childCheckbox.dispatchEvent(new Event("change"));
    }
  });
};

A Quick Note About React Best Practices

While manually manipulating the DOM works for your use case, React's core philosophy is to drive UI changes through state. Whenever possible, it's better to update your treeData or checkedKeys state instead of touching the DOM directly. For example, you could write a recursive function to update the checked property of the current node, its parent, and children, then call setState to re-render the Tree. This avoids potential inconsistencies between your state and the actual DOM.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:43:56