Make it to make it

いろいろ作ってアウトプットするブログ

Controlled vs Uncontrolled componentsとrefの使い方

Reactでは、状態管理がDOMではなくReact componentで行われる。 Reactなしである場合、例えばformのinput要素の状態を取ってくる場合は従来はDOM操作によって取ってくるという手法だった。

ではどちらの方法がベターであるのか? この質問に付随して出てくるのがControlled componentsとUncontrolled componentsである。

Controlled components

Controlled componentsでは、状態管理をReactのスタイルに沿って行う。 formやinputの状態は全て属するコンポーネントのstateで管理されるので、各値を更新する場合はstateを更新することになる。

Uncontrolled components

Uncontrolled componentsでは、コンポーネントによる状態管理はなく、コンポーネントの状態は各inputで各々持つ。 つまりDOM内に状態が存在するので、更新するにはDOM操作を行う必要がある。

refを使用したinputのDOMでの状態管理

Controlled

Form.js

class Form extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      email: ''
    }

    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
  }
  handleChange(e) {
    this.setState({
      email: e.target.value
    })
  }
  handleSubmit() {
    alert('The email is ' + this.state.email)
  }
  render() {
    return (
      <div>
        <pre>The email is {this.state.email}</pre>
        <br />
        <input
          type='text'
          placeholder='Email'
          value={this.state.email}
          onChange={this.handleChange}
        />
        <button onClick={this.handleSubmit}>Submit</button>
      </div>
    )
  }
}

こちらの例の場合は、状態はコンポーネントのstateが持っていることになる。 このコードを、Uncontrolled componentsにしてDOMでの状態管理ができるようにしてみる。

Uncontrolled

Form.js

class Form extends React.Component {
  constructor(props) {
    super(props)

    this.input = React.createRef('')
    this.handleSubmit = this.handleSubmit.bind(this)
  }
  handleSubmit() {
    alert('The email is ' + this.input.current.value)
  }
  render() {
    return (
      <div>
        <input
          type='text'
          placeholder='Email'
          ref={this.input}
        />
        <button onClick={this.handleSubmit}>Submit</button>
      </div>
    )
  }
}

refのpropをinputフィールドに持たせ、値を取得する際にはthis.input.current.valueで持ってくることができる。

どちらを使用すべきか?

結論からいうとControlled componentsで書いた方がよい。 Reactに状態管理を委ねる方が、変更にたいしてリアクティブなUIを作ることができるから。