【问题标题】:What is the difference between using constructor vs getInitialState in React / React Native?在 React / React Native 中使用构造函数与 getInitialState 有什么区别?
【发布时间】:2015-08-20 12:14:30
【问题描述】:

我见过两者可以互换使用。

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

【问题讨论】:

    标签: reactjs react-native constructor


    【解决方案1】:

    这两种方法不可互换。使用 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 */ };
      },
    });
    

    【讨论】:

    • 使用 setState 代替 this.state = 是否更好?
    • 在构造函数中,你应该总是直接赋值给this.state。请注意,这是唯一允许这样做的地方。您应该在其他任何地方使用this.setState()
    • 除非您正在使用它,否则您不需要将props 作为参数添加到构造函数。同样super() 在这里也可以
    • @inostia React 文档建议始终将props 传递给super() (facebook.github.io/react/docs/…)。但我不知道该建议的原因。你是对的,实际上不需要将props 传递给super(),因为this.props 仍然可以在render() 和其他方法中访问。也许建议是为了与潜在的未来功能兼容。
    • @TaylorEdmiston 您需要直接修改this.state。我建议制作接受(state, props) 并返回新状态的函数,这样您就可以在构造函数中执行this.state = myFn(null, props) 或在其他任何地方执行this.setState(myFn)
    【解决方案2】:

    constructorgetInitialState 的区别在于 ES6ES5 本身的区别。
    getInitialStateReact.createClass
    一起使用br>constructorReact.Component 一起使用。

    因此问题归结为使用 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 和 facebook 的content on autobinding

    constructor 也可用于处理此类情况。要将方法绑定到组件实例,可以在constructor 中预先绑定。 This 是做这些很酷的事情的好材料。

    更多关于最佳实践的好材料
    Best Practices for Component State in React.js
    Converting React project from ES5 to ES6

    更新:2019 年 4 月 9 日,

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

    你可以的

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

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

    使用 React Hooks

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

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

    import React, { useState } from 'react';
    
    function TodoApp () {
      const items = useState([]);
    

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

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

    【讨论】:

    • 区别在于你使用的ES版本
    • 不是还有第三种构造对象的方法,作为功能性“状态挂钩”吗? reactjs.org/docs/hooks-state.html我是 react-native 新手,所以我可能错了。
    • 嗨@djangofan,我想更新这个已经有一段时间了。谢谢你把我推向那个方向。我添加了带有类字段的新简写和带有 React 钩子的 useState
    • 您能解释一下super() 是什么以及为什么我们将道具作为参数传递给它们吗? @sudobangbang
    【解决方案3】:

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

    constructor 是你的类被初始化的地方...

    构造函数

    构造方法是一种特殊的方法,用于创建和 初始化使用类创建的对象。只能有一个 类中名称为“构造函数”的特殊方法。语法错误 如果类包含不止一次出现的 a 构造方法。

    构造函数可以使用 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};
      },
      // ...
    });
    

    访问here了解更多信息。

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

    【讨论】:

    • 我建议将componentWillReceiveProps 添加到图表中,因为 OP 是关于组件中的状态。
    • 您能解释一下super() 是什么以及为什么我们将道具作为参数传递给它们吗? @Alireza
    【解决方案4】:

    如果您使用 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({
    
    });
    

    【讨论】:

      【解决方案5】:

      这些天我们不必在组件内部调用构造函数——我们可以直接调用state={something:""},否则之前我们首先需要用super()声明构造函数来继承React.Component类的所有东西 然后在构造函数中初始化我们的状态。

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

      【讨论】:

        【解决方案6】:

        最大的区别在于它们从哪里开始,因此构造函数是 JavaScript 中类的构造函数,另一方面,getInitialState 是 React 生命周期的一部分。构造函数方法是一种特殊的方法,用于创建和初始化使用类创建的对象。

        【讨论】:

          【解决方案7】:

          React 中的构造函数和 getInitialState 都是用来初始化状态的,但不能互换使用。这两者的区别在于我们在使用 ES6 类时应该在构造函数中初始化状态,而在使用 React.createClass(ES5 语法)时定义 getInitialState 方法。所以constructor和getInitialState的区别就是ES6和ES5本身的区别。

          【讨论】:

            【解决方案8】:

            React Native 中的 constructorgetInitialState 都是用来初始化状态的,但不能互换使用。 这两者的区别在于,我们在使用 ES6 类时要在构造函数中初始化状态,而在使用 React.createClass(ES5 语法)时要定义 getInitialState 方法。

            我们在 React.createClass 中使用 getInitialState,在 React.Component 中使用 constructor

            这是一个例子:

            1. 构造函数
            class ReactModule extends React.Component {
            constructor(props) {
              super(props);
              this.state = { /*state */ };
            }
            }
            
            
            1. 获取初始状态
            var ReactModule = React.createClass({
            getInitialState() {
              return { /*state */ };
            },
            });
            

            【讨论】:

              【解决方案9】:

              构造函数 构造函数是在从类创建对象期间自动调用的方法。 ...简单地说,构造函数有助于构造事物。在 React 中,构造函数也不例外。它可用于将事件处理程序绑定到组件和/或初始化组件的本地状态。2019 年 1 月 23 日

              获取初始状态 在 ES6 类中,您可以通过在构造函数中分配 this.state 来定义初始状态:

              看看这个例子

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

              使用 createReactClass(),您必须提供一个单独的 getInitialState 方法来返回初始状态:

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
                猜你喜欢
                • 2018-08-09
                • 2016-12-03
                • 2016-04-11
                • 2021-11-02
                • 2019-01-01
                • 2017-08-04
                • 2021-01-01
                • 2020-08-07
                相关资源
                最近更新 更多