【问题标题】:How do you get the name of a ref?你如何获得裁判的名字?
【发布时间】:2020-04-19 04:38:20
【问题描述】:

假设你有这个 JSX:

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

如果你想获取 ref 的名称并将其添加到你的状态,你会怎么做?

类似:

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')
      })
    }
  }

【问题讨论】:

  • 引用没有名字。您是指 ref 所在的属性的名称吗?还是 ref 所指的 DOM 元素的 name 属性? (div 元素没有names,它们只有global attributesname 不是其中之一...)或标签名称(在您的示例中为"div")?跨度>
  • 如果它没有名字你想怎么得到它?您应该指定一个名称
  • 对不起,我的问题不清楚。我想为每个 ref 分配一个名称,以便以后可以使用它
  • @A7DC 您需要在 this.divRef = React.createRef() 之类的构造函数部分声明引用构造函数,然后您可以使用 在页面上的任何位置使用该引用this.divRef.current

标签: javascript reactjs typescript ref


【解决方案1】:

在你说过的评论中:

我想为每个 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-* attribute 来表示:

// 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);
}

【讨论】:

  • 这太好了,谢谢 T.J!我认为 data-* 属性方法是我正在寻找的方法
猜你喜欢
  • 2010-11-01
  • 2015-01-07
  • 2010-09-22
  • 2014-01-30
  • 2011-04-29
  • 2021-03-04
  • 2022-09-27
  • 2018-08-16
相关资源
最近更新 更多