web-dev-qa-db-ja.com

React/React NativeでコンストラクタとgetInitialStateを使用することの違いは何ですか?

私は両方が互換的に使われているのを見ました。

両方の主な使用例は何ですか?長所/短所はありますか?もっと良いやり方はありますか?

535
Nader Dabit

2つのアプローチは互換性がありません。 ES6クラスを使用するときはコンストラクタでstateを初期化し、React.createClassを使用するときはgetInitialStateメソッドを定義する必要があります。

ES6クラスの主題に関する公式のReactドキュメントを参照してください

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { /* initial state */ };
  }
}

と同等です

var MyComponent = React.createClass({
  getInitialState() {
    return { /* initial state */ };
  },
});
821

constructorgetInitialStateの違いは、 ES6 ES5 自体の違いです。
getInitialStateReact.createClassおよび
constructorReact.Componentと共に使用されます。

したがって、質問は ES6 または ES5 を使用することの長所/短所に帰着します。

コードの違いを見てみましょう

ES5

var TodoApp = React.createClass({ 
  propTypes: {
    title: PropTypes.string.isRequired
  },
  getInitialState () { 
    return {
      items: []
    }; 
  }
});

ES6

class TodoApp extends React.Component {
  constructor () {
    super()
    this.state = {
      items: []
    }
  }
};

これに関して興味深い reddit thread があります。

実際のコミュニティは ES6 に近づいています。また、それはベストプラクティスと見なされています。

React.createClassReact.Componentの間にはいくつかの違いがあります。たとえば、これらの場合にthisがどのように処理されるかなどです。そのような違いについてもっと読む このブログ記事内 とfacebookの 自動バインディングの内容

constructorはそのような状況を扱うためにも使うことができます。メソッドをコンポーネントインスタンスにバインドするために、それをconstructorの中にあらかじめバインドすることができます。 This はそのようなクールなことをするのに良い材料です。

ベストプラクティスに関するもう少し優れた資料
React.jsのコンポーネント状態のベストプラクティス
ES5からES6へのReactプロジェクトの変換

更新:2019年4月9日

JavascriptクラスAPIの新しい変更により、コンストラクタは不要です。

あなたはできる

class TodoApp extends React.Component {

    this.state = {items: []}
};

これはまだコンストラクタ形式に変換されますが、心配する必要はありません。もっと読みやすい形式を使用できます。

react hooks image Reactフック付き

Reactバージョン16.8から、新しいAPI Called hooksがあります。

今、あなたは状態を持つためにクラスコンポーネントさえも必要としません。機能的なコンポーネントでも可能です。

import React, { useState } from 'react';

function TodoApp () {
  const items = useState([]);

初期状態はuseStateの引数として渡されることに注意してください。 useState([]

反応フックについてもっと読む 公式ドキュメントより

129
sudo bangbang

確かに、大きな違いはそれらがどこから来ているかから始まる、それでconstructorはJavaScriptにおけるあなたのクラスのコンストラクタです、他方で、getInitialStatelifecycleReactの一部です。

constructorはあなたのクラスが初期化される場所です...

コンストラクタ

コンストラクタメソッドは、クラスで作成されたオブジェクトを作成および初期化するための特別なメソッドです。クラス内に "コンストラクター"という名前の特別なメソッドは1つしか存在できません。クラスに複数のコンストラクタメソッドが含まれる場合、SyntaxErrorがスローされます。

コンストラクターはsuperキーワードを使用して、親クラスのコンストラクターを呼び出すことができます。

React v16のドキュメントでは、彼らは好みを述べていませんが、createReactClass()...を使う場合はgetInitialStateにする必要があります。

初期状態を設定する

ES6クラスでは、コンストラクターでthis.stateを割り当てることで初期状態を定義できます。

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}

CreateReactClass()では、初期状態を返す個別のgetInitialStateメソッドを提供する必要があります。

var Counter = createReactClass({
  getInitialState: function() {
    return {count: this.props.initialCount};
  },
  // ...
});

詳細については/ ここ をご覧ください。

下の画像も作成してReact Compoenentsのライフサイクルをいくつか示しています。

React lifecycle

26
Alireza

ES6でReact-Nativeクラスを書いている場合は、以下のフォーマットに従います。それはネットワーク呼び出しをするクラスのためのRNのライフサイクルメソッドを含みます。

import React, {Component} from 'react';
import {
     AppRegistry, StyleSheet, View, Text, Image
     ToastAndroid
} from 'react-native';
import * as Progress from 'react-native-progress';

export default class RNClass extends Component{
     constructor(props){
          super(props);

          this.state= {
               uri: this.props.uri,
               loading:false
          }
     }

     renderLoadingView(){
          return(
               <View style={{justifyContent:'center',alignItems:'center',flex:1}}>
                    <Progress.Circle size={30} indeterminate={true} />
                    <Text>
                        Loading Data...
                    </Text>
               </View>
          );
     }

     renderLoadedView(){
          return(
               <View>

               </View>
          );
     }

     fetchData(){
          fetch(this.state.uri)
               .then((response) => response.json())
               .then((result)=>{

               })
               .done();

               this.setState({
                         loading:true
               });
               this.renderLoadedView();
     }

     componentDidMount(){
          this.fetchData();
     }

     render(){
          if(!this.state.loading){
               return(
                    this.renderLoadingView()
               );
          }

          else{

               return(
                    this.renderLoadedView()
               );
          }
     }
}

var style = StyleSheet.create({

});

最近では、コンポーネント内でコンストラクタを呼び出す必要はありません - 直接state={something:""}を呼び出すことができます。それ以外の場合は、最初にReact.Component classからすべてのものを継承するためにsuper()を使用してコンストラクタを宣言します。私たちの状態を初期化します。

React.createClassを使用する場合はgetInitialStateメソッドで初期化状態を定義してください。

0
user11192787