使用条件渲染将React set焦点放在input [type =“number”]上

时间:2017-10-02 12:35:57

标签: javascript reactjs firefox focus

在阅读React set focusReact focus with timeout之后,我仍然有点困惑在输入上设置focus的正确的跨浏览器选项。

条件渲染输入有问题,在table中渲染后可能会有焦点,其中input位于td

1)使用 componentDidUpdate 的解决方案:

//...
componentDidUpdate() {
  this.input && this.input.focus();
}

render() {
  const show = this.state.isShown;

  return (
    <td className="editable">
      {!show ? (
        <input
          type="number"
          ref={(input) => { this.input = input }}
          value={this.state.value}
          onBlur={this.save}
          onKeyPress={e =>
            e.which === 13 || e.keyCode === 13 ? this.save() : null}
      />
    ) : (
        <span onClick={this.onTdClick}>{this.props.name}</span>
      )}
    </td>
  );
}

此解决方案适用于Chrome,IE11,Edge,但在最新的Firefox中不起作用(点击span后输入事件不会显示。

2)使用 requestAnimationFrame 的解决方案:

//...
componentDidUpdate() {
  if (!this.state.isShown) {
    requestAnimationFrame(() => {
      this.input && this.input.focus();
    })
  }
}

render() {
  // same above
}

此解决方案适用于Chrome,IE11,Edge,但在尝试设置focus时Firefox仍未显示输入。

3)解决方案 setTimeout(回调,n)

  //...
  componentDidUpdate() {
    if (!this.state.isShown) {
      setTimeout(() => {
        this.input && this.input.focus()
      }, 50);
    }
  }

  render() {
   // same above
  }

此案例适用于Chrome,IE11,Edge和(最终)Firefox,但似乎这是最“丑陋”的。

P.S。 autoFocus attr不是这种情况,这里我有条件渲染,所以需要在click.之后设置焦点

所以,我的问题是:我们是否有正确的方法来解决这个没有为Firefox设置setTimeout的问题?

实时测试示例:codepen

1 个答案:

答案 0 :(得分:1)

Observable.combineLatest(
    studentService.fetchTotal(),
    classesService.fetchTotal(),
    gradesService.fetchTotal(),
    (studentTotal, classesTotal, gradesTotal) -> {
        // do your stuff
        return studentTotal + classesTotal + gradesTotal;
    })
    .subscribe(
        total -> System.out.println(total)
    )
);

import React from 'react'; const MyInput = React.createClass({ componentDidMount(){ this.elem.focus(); }, render(){ return( <input ref={(elem) => {this.elem = elem}} type="text" /> ); } }); export default MyInput; 渲染到您想要的位置。渲染后它将具有焦点。在Safari,Chrome,Firefox上测试过。