В чем разница между использованием конструктора и getInitialState в React/React Native?

Я видел, что оба используются взаимозаменяемо.

Каковы основные варианты использования для обоих? Есть ли преимущества/недостатки? Является ли практика лучшей?

Ответы

Ответ 1

Эти два подхода не являются взаимозаменяемыми. Вы должны инициализировать состояние в конструкторе при использовании классов ES6 и определить метод getInitialState при использовании React.createClass.

См. Официальный документ React по теме ES6.

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

эквивалентно

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

Ответ 2

Разница между constructor и getInitialState - это разница между ES6 и ES5.
getInitialState используется с React.createClass и
constructor используется с React.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.

Сообщество React приближается к ES6. Также это считается лучшей практикой.

Есть некоторые различия между React.createClass и React.Component. Например, как обрабатывается this в этих случаях. Подробнее о таких различиях читайте в этом посте и в фейсбуке об автосвязывании

constructor также может быть использован для обработки таких ситуаций. Чтобы привязать методы к экземпляру компонента, его можно предварительно связать в constructor. Этот - хороший материал для таких крутых вещей.

Еще несколько хороших материалов о лучших практиках
Лучшие практики для состояния компонентов в React.js
Преобразование проекта React из ES5 в ES6

Обновление: 9 апреля 2019 года:

С новыми изменениями в API класса Javascript вам не нужен конструктор.

Вы могли бы сделать

class TodoApp extends React.Component {

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

Это все равно будет перенесено в формат конструктора, но вам не придется об этом беспокоиться. Вы можете использовать этот формат, который является более читабельным.

react hooks image с реактивными крючками

Начиная с версии React 16.8, появился новый API Called hooks.

Теперь вам даже не нужен компонент класса, чтобы иметь состояние. Это даже можно сделать в функциональном компоненте.

import React, { useState } from 'react';

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

Обратите внимание, что начальное состояние передается в качестве аргумента useState; useState([])

Подробнее о реакционных крючках читайте в официальных документах.

Ответ 3

Хорошо, большая разница начинается с того, откуда они идут, поэтому constructor является конструктором вашего класса в JavaScript, с другой стороны, getInitialState является частью lifecycle React.

constructor, где ваш класс инициализируется...

Конструктор

Метод конструктора является специальным методом для создания и инициализации объекта, созданного с помощью класса. В классе может быть только один специальный метод с именем "конструктор". Синтаксическая ошибка будет выбрана, если класс содержит более одного вхождения метода конструктора.

Конструктор может использовать ключевое слово super для вызова конструктора родительского класса.

В документе React v16 они не упомянули никаких предпочтений, но вам нужно getInitialState если вы используете createReactClass()...

Установка начального состояния

В классах 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

Ответ 4

Если вы пишете класс React-Native с ES6, будет следовать следующий формат. Он включает методы жизненного цикла 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({

});

Ответ 5

В наши дни нам не нужно вызывать конструктор внутри компонента - мы можем напрямую вызывать state={something:""}, в противном случае ранее сначала мы должны объявить конструктор с помощью super() чтобы потом наследовать все от класса React.Component внутри конструктора мы инициализируем наше состояние.

Если используется React.createClass определите состояние инициализации с getInitialState метода getInitialState.