在 React / React Native 中使用构造函数与 getInitialState 有什么区别?

What is the difference between using constructor vs getInitialState in React / React Native?

我看到两者可以互换使用。

两者的主要用例是什么?有优点/缺点吗?一个是更好的做法吗?

这两种方法不可互换。使用 ES6 类 时应在构造函数中初始化状态,使用 React.createClass.

时应定义 getInitialState 方法

See the official React doc on the subject of ES6 classes.

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

等同于

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

constructorgetInitialState的区别就是ES6ES5本身的区别
getInitialStateReact.createClass
一起使用 constructorReact.Component 一起使用。

因此问题归结为 advantages/disadvantages 使用 ES6ES5.

让我们看看代码的区别

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

React 社区正在向 ES6 靠拢。它也被认为是最佳实践。

React.createClassReact.Component 之间存在一些差异。例如,在这些情况下如何处理 this。详细了解此类差异 in this blogpost and facebook's content on autobinding

constructor也可以用来处理这种情况。要将方法绑定到组件实例,可以在 constructor 中预先绑定它。 This 是一个很好的 material 来做这么酷的事情。

一些更好的material最佳实践
Best Practices for Component State in React.js
Converting React project from ES5 to ES6

更新:2019 年 4 月 9 日,

随着 Javascript class API 中的新变化,您不需要构造函数。

你可以做到

class TodoApp extends React.Component {

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

这仍然会被转译为构造函数格式,但您不必担心。您可以使用这种更具可读性的格式。

使用 React Hooks

从 React 版本 16.8 开始,有一个新的 API 称为钩子。

现在,您甚至不需要 class 组件来拥有状态。它甚至可以在功能组件中完成。

import React, { useState } from 'react';

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

请注意,初始状态作为参数传递给 useStateuseState([])

阅读更多关于反应钩子的信息from the official docs

如果你用 ES6 编写 React-Native class,将遵循以下格式。它包括用于 class 进行网络调用的 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({

});

好的,最大的不同是从它们的来源开始,所以 constructor 是 JavaScript 中 class 的构造函数,另一方面,getInitialStateReactlifecycle 的一部分。

constructor 是您的 class 初始化的地方...

Constructor

The constructor method is a special method for creating and initializing an object created with a class. There can only be one special method with the name "constructor" in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method.

A constructor can use the super keyword to call the constructor of a parent class.

在 React v16 文档中,他们没有提到任何偏好,但如果您使用 createReactClass()...

,则需要 getInitialState

Setting the Initial State

In ES6 classes, you can define the initial state by assigning this.state in the constructor:

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

With createReactClass(), you have to provide a separate getInitialState method that returns the initial state:

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

访问 here 了解更多信息。

还创建了下图以显示 React 组件的几个生命周期:

现在我们不必在组件内部调用构造函数 - 我们可以直接调用 state={something:""},否则之前我们先用 super() 声明构造函数来继承 super() 的所有内容=12=] class 然后在构造函数中我们初始化我们的状态。

如果使用 React.createClass,则使用 getInitialState 方法定义初始化状态。

最大的区别是从它们的来源开始,所以构造函数是 JavaScript 中 class 的构造函数,另一方面, getInitialState 是 React 生命周期的一部分。构造函数方法是一种特殊的方法,用于创建和初始化使用 class.

创建的对象

在构造函数中,我们应该始终初始化状态。