首页 > 解决方案 > 你如何获得裁判的名字?

问题描述

假设你有这个 JSX:

<div ref={this.divRef}>
  <SomeComponent />
</div>

你想得到 ref 的名字并将它添加到你的 state 中,你会怎么做?

就像是:

componentDidMount() {
    // get all the positions of the current sections
    if (this.divRef.current) {
      this.setState({
        breakpoints: [{
          name: this.divRef.current.name,
          position: this.divRef.current.getBoundingClientRect().bottom,
        }],
      }, () => {
          // tslint:disable-next-line:no-console
          console.log(this.divRef.current, 'this.divRef.current')
      })
    }
  }

标签: javascriptreactjstypescriptref

解决方案


在评论中你说:

我想为每个 ref 分配一个名称,以便以后可以使用它

如果您真的是指ref,那么我能想到的唯一可靠方法是使用由 ref 键入的 WeakMap 。(尽管您可以使用以符号命名的属性,下面会详细介绍。)

在您的构造函数中创建 WeakMap(或在您的模块中,我不知道需要多少代码才能使用这些名称);

this.nameMap = new WeakMap();

然后当您需要获取/分配名称时:

let name = this.nameMap.get(this.divRef);
if (!name) {
    name = "some appropriate name";
    this.nameMap.set(this.divRef, name);
}

可以使用以符号命名的属性将名称存储在 ref 对象本身上,但通常在您的代码无法控制的对象上存储任意属性并不是一个好主意。但为了完整起见,您将在构造函数(或模块)中创建符号:

this.nameKey = Symbol("refname");

然后使用它:

// I don't recommend this
let name = this.divRef[this.nameKey];
if (!name) {
    name = "some appropriate name";
    this.divRef[this.nameKey] = name;
}

但我不推荐它。带有 Symbol 的环境也会有 WeakMap,我会在这里使用它。


但是,如果您指的是 ref 当前所指的元素,则可以为此使用data-*属性

// Assuming you've checked that `current` isn't `null`
let name = this.divRef.getAttribute("data-name");
if (!name) {
    name = "some appropriate name";
    this.divRef.setAttribute("data-name", name);
}

如果您可以承担dataset支持,则可以dataset改用:

// Assuming you've checked that `current` isn't `null`
let name = this.divRef.dataset.name;
if (!name) {
    name = "some appropriate name";
    this.divRef.dataset.name = name;
}

也就是说,WeakMap 解决方案对于元素和 refs 一样有效:

let name = this.nameMap.get(this.divRef.current);
if (!name) {
    name = "some appropriate name";
    this.nameMap.set(this.divRef.current, name);
}

推荐阅读