Help us understand the problem. What is going on with this article?

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

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

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした