如果没有 setTimeout,ReactJS 组件内的 HTML 文本区域无法以编程方式选择?

Ste*_*ino 5 html javascript reactjs

我有一个 ReactJS 组件,<textarea>里面有一个 HTML。

已预先填充<textarea>属性value(见下文...我正在生成一个链接供用户复制)。

我想自动选择<textarea>内容,这样用户复制文本会更方便。我正在尝试在 ReactcomponentDidMount调用中执行此操作。它有效......有点

据我所知,该组件的安装速度非常缓慢,即使componentDidMount已经被调用,该过程仍在进行中。我这么说的原因是:如果我myTextarea.select()直接在内部调用componentDidMount,100% 都会失败。但是,如果我拨打.select()电话setTimeout(...),让它在尝试选择内容之前稍等一下,那么它100% 都能正常工作。

编辑/注意:经过一番探索后,我发现一些观点表明,用于setTimeout(...)此目的的做法是不好的做法,所以现在我更加渴望避免使用它。

我可能会缺少什么,有没有更好的方法来实现这一点?

这就是我所拥有的。

这个版本失败了。

var GenerateLinkUi = React.createClass({
  componentDidMount: function() {
    document.getElementById('cyoag-generated-link-textarea').select();
  },
  render: function () {
    return (
      <div id='cyoag-generate-link-ui'>
        <textarea readOnly id='cyoag-generated-link-textarea' value={config.hostDomain + 'link?id=' + this.props.nodeUid} />
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

这个版本成功了。

var GenerateLinkUi = React.createClass({
  componentDidMount: function() {
    setTimeout(function(){
      document.getElementById('cyoag-generated-link-textarea').select();
    }, 500);
  },
  render: function () {
    return (
      <div id='cyoag-generate-link-ui'>
        <textarea readOnly id='cyoag-generated-link-textarea' value={config.hostDomain + 'link?id=' + this.props.nodeUid} />
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

编辑:这被标记为重复。链接的问题给我提出了更多问题,但没有提供明确的答案,如下面的评论中所述。如果ref在组件安装后执行,并且componentDidMount也在组件安装“之后”执行,我很难理解两者之间的区别,除了将refDOM 元素作为参数传递这一事实之外;我必须在哪里componentDidMount使用document.getElementById什么东西。如果有人能描述两者之间更深层次的差异,我将不胜感激。

与此同时,我找到了解决此问题的其他解决方法,但我仍然渴望了解有关该主题的更多信息。

Mar*_*son 1

我会猜测发生了什么。

组件会componentDidMount再次渲染吗?我想它会再次渲染textarea并覆盖,select()因为你是在实际 DOM 而不是虚拟 DOM 上完成的。

它在使用 setTimeout 时有效,因为您在 后发生的所有渲染之后执行此操作componentDidMount。我想如果你再次更新道具,它会select()再次覆盖。

使用 ref 来解决这个问题。

var GenerateLinkUi = React.createClass({
  componentDidMount: function() {
    this.textArea.select();
  },
  setTextArea: function(ref) {
    this.textArea = ref;
  }
  render: function () {
    return (
      <div id='cyoag-generate-link-ui'>
        <textarea ref={this.setTextArea} readOnly id='cyoag-generated-link-textarea' value={config.hostDomain + 'link?id=' + this.props.nodeUid} />
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)