1. ホーム
  2. ジャバスクリプト

[解決済み】Reactコンポーネントはpropsから状態を初期化する

2022-04-01 01:19:24

質問

Reactでは、この2つの実装の間に実際の違いはあるのでしょうか? 一部の友人からは FirstComponent がパターンですが、その理由がわかりません。その SecondComponent は、レンダーが一度だけ呼び出されるため、よりシンプルに見えます。

まず

import React, { PropTypes } from 'react'

class FirstComponent extends React.Component {

  state = {
    description: ''
  }

  componentDidMount() {
    const { description} = this.props;
    this.setState({ description });
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} /> 
    );
  }
}

export default FirstComponent;

2番目

import React, { PropTypes } from 'react'

class SecondComponent extends React.Component {

  state = {
    description: ''
  }

  constructor (props) => {
    const { description } = props;
    this.state = {description};
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} />   
    );
  }
}

export default SecondComponent;

更新しました。 私は setState() から this.state = {} (joewsさんありがとうございます), しかし、まだ違いが分かりません。一方が他方より優れているのでしょうか?

解決方法は?

注意すべきは、決して変化しないプロパティをステートにコピーするのはアンチパターンであるということです(その場合は.propsに直接アクセスすればよいのです)。いずれは変更されるが .props からの値で始まるステート変数がある場合、コンストラクタ呼び出しさえ必要ありません - これらのローカル変数は、親のコンストラクタを呼び出した後に初期化されます。

class FirstComponent extends React.Component {
  state = {
    x: this.props.initialX,
    // You can even call functions and class methods:
    y: this.someMethod(this.props.initialY),
  };
}

これは、以下の@joewsの回答に相当する略語です。これは es6 トランスパイラの最近のバージョンでのみ動作するようで、私はいくつかの webpack のセットアップで問題が発生しました。もしこれがうまくいかない場合は、babel プラグインを追加してみてください。 babel-plugin-transform-class-properties または、以下の@joewsによる非短縮形バージョンを使用することができます。