読者です 読者をやめる 読者になる 読者になる

Reactで動的に生成したformでautofocus

Reactで、動的にformを生成した時に、そのformが生成された時にautofocusを当てたいという場面がありました。

以下を参考に。

reactjs - React set focus on input after render - Stack Overflow

componentDidUpdateでObjectを指定してfocus()メソッドを使う。

ライフサイクルの一覧は以下が非常に参考になる。

qiita.com

refでComponentに対する参照を取得できます。

React.jsでPropやStateを使ってComponent間のやりとりをする - Qiita

HTML側でclassを指定しておいてそれをrefで参照します。例えば、

<input type="text" ref="promotionCodeInput" />

みたいな感じにすれば、

this.refs.promotionCodeInput.getDOMNode()

みたいな感じで取得できそうです。refは、なんとなくメソッド名っぽい感じで命名しとくんですね。

Reactでは直接DOMをいじることはない(というかいじらないようにしようね、という方針)なので、getDOMNode()で取得したDOMは書き換えないようにしましょう。メソッド名がその意図を体現している。

React.jsでPropやStateを使ってComponent間のやりとりをする - Qiita

ということで最終的なコードは以下のような感じになりました。isEditingというstateを親が管理していて、これがtrueのときだけformが表示されるのですが、その際にautofocusしましょう、って感じです。

var PromotionCodeForm = React.createClass({
  componentDidUpdate: function() {
    if(this.refs.promotionCodeInput) {
      this.refs.promotionCodeInput.getDOMNode().focus();
    }
  },
  render: function() {
    if(this.props.isEditing) {
      return (
        <div>
          <form onSubmit={this.handleSubmit}>
            <input type="text" ref="promotionCodeInput" />
            <button type="submit" name="action">更新</button>
          </form>
        </div>
      );
    }else {
      return (
        <div></div>
      );
    }
  }
});

課題として、autofocusがあたってもvalueが入っているとカーソルがテキストの先頭にきてしまいます。これどうにかできないかなー。