ReactJS组件中的HTML textarea不能在没有setTimeout的情况下以编程方式选择吗?

时间:2017-01-24 08:05:40

标签: javascript html reactjs

我有一个内部带有HTML <textarea>的ReactJS组件。

<textarea>预先填充了value属性(请参阅下文...我正在生成供用户复制的链接)。

我想自动选择<textarea>内容,以便用户更方便地复制文本。我试图在React componentDidMount电话中执行此操作。它有效...... 有点

尽管我已经知道,组件安装速度非常慢,即使已经调用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>
    );
  }
});

此版本成功。

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

编辑:这被标记为重复。相关问题为我提出了更多问题,并没有提供明确的答案,如下面的评论所述。如果在组件安装后执行ref,则componentDidMount也会在&#34;之后执行&#34;组件安装,我很难理解两者之间的区别,超出了ref将DOM元素作为arg传递的事实; componentDidMount中我必须使用document.getElementById或其他内容。如果有人能描述两者之间更深层次的差异,我会很感激。

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

2 个答案:

答案 0 :(得分:1)

我会猜测发生了什么。

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

使用setTimeout时有效,因为在componentDidMount之后发生的所有渲染之后都会这样做。我想如果你再次更新道具,它会再次覆盖select()

使用refs来解决这个问题。

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

答案 1 :(得分:1)

这样做的技术称为refs callback

  

React支持可以附加到任何组件的特殊属性。 ref属性采用回调函数,并且在安装或卸载组件后立即执行回调。

顺便说一下,您使用的是正确的componentDidMount方法。

参考资料在那里

enter image description here

它存在于ReactClass中。