LoginSignup
1
2

More than 3 years have passed since last update.

React.Componentのメンバ変数は、再レンダー時に更新されるとは限らない!

Last updated at Posted at 2020-01-22

ReactでsetState()しても値が更新されなくてハマったので、記事化します。

更新すべき値をメンバ変数に格納した場合

ボタンを押すと値が+1されるアプリケーションを作ります。

以下は間違ったコードです。
Appでカウンターの値を管理し、Counterはその値とカウントボタンを表示します。

app.js
import React from 'react'
import ReactDOM from 'react-dom'
import Counter from './counter'

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {count: 0}
    this.increment = this.increment.bind(this)
  }

  increment() {
    this.setState(
      (state) => {return {count: state.count + 1}}
    )
  }

  render() {
    return (
      <Counter count={this.state.count} onClick={this.increment} />
    )
  }
}

let app = document.getElementById('app')
ReactDOM.render(<App />, app)

counter.js
import React from 'react'

class Counter extends React.Component {
  constructor(props) {
    super(props)
    this.count = this.props.count
  }

  render() {
    // 以下の`this.count`は、新しいpropsを反映しない!
    return (
      <div>
        <p>{this.count}</p>
        <button onClick={this.props.onClick}>カウント</button>
      </div>
    )
  }
}

export default Counter

このコードを実行し、ボタンをクリックしても、カウンターの値は増加しないと思います。

レンダーごとに更新する値は、メンバ変数に保存しない

値が更新されない原因は、表示する値がthis.countになっていることです。
counter.jsを以下のように修正すれば、ちゃんとカウント値が増加します。

counter.js
import React from 'react'

class Counter extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        <p>{this.props.count}</p>
        <button onClick={this.props.onClick}>カウント</button>
      </div>
    )
  }
}

export default Counter

今回は、this.props.countを表示するだけなので、わざわざメンバ変数に格納することはありませんが、表示させるべき値が複雑になる場合、renderメソッドの戻り値に直接式を書かずに、結果を変数に格納したい場合があります。そういう場合は、たとえば関数にすると良いと思います。

counter.js
class Counter extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    let count = this._getCount()
    return (
      <div>
        <p>{count}</p>
        <button onClick={this.props.onClick}>カウント</button>
      </div>
    )
  }

  _getCount() {
    let count;
    // すごく複雑な処理
    return count
  }
}

以上です。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2