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

Nad*_*bit 581 constructor reactjs react-native

我看过两者都可以互换使用.

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

Ale*_*erg 895

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

请参阅有关ES6课程主题的官方React文档.

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

相当于

var MyComponent = React.createClass({
  getInitialState() {
    return { /* initial state */ };
  },
});
Run Code Online (Sandbox Code Playgroud)

  • 在构造函数中,您应该始终直接分配给`this.state`.请注意,这是唯一允许此操作的地方.你应该在其他地方使用`this.setState()`. (210认同)
  • 是否更好地使用setState而不是this.state =? (9认同)
  • 除非你正在使用它,否则你不需要将`props`作为参数添加到构造函数中.同样``super()`在这里也没关系 (9认同)
  • @inostia React文档建议始终将`props`传递给`super()`(https://facebook.github.io/react/docs/state-and-lifecycle.html#adding-local-state-to-a -类).但我不知道推荐的原因.你是对的,将`props`传递给`super()`实际上并不是必需的,因为`this.props`仍然可以在`render()`和其他方法中访问.也许建议是为了兼容潜在的未来功能. (6认同)
  • @TaylorEdmiston您需要直接修改`this.state`.我建议创建一个接受`(state,props)`并返回一个新状态的函数,这样你就可以在构造函数中执行`this.state = myFn(null,props)`或者`this.setState(myFn) )`其他地方. (5认同)

sud*_*ang 143

constructor和之间getInitialState的区别是ES6ES5本身之间的区别.
getInitialState与...一起使用React.createClass
constructor使用React.Component.

因此,问题归结为使用ES6ES5的优点/缺点.

我们来看看代码的差异

ES5

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

ES6

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

有一个有趣的reddit线程.

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

React.createClass和之间存在一些差异React.Component.例如,this在这些情况下如何处理.阅读更多关于此博客帖子和facebook的自动绑定内容的差异

constructor也可以用来处理这种情况.要将方法绑定到组件实例,可以将其预先绑定在constructor.是做这么酷的东西的好材料.

关于最佳实践的一些更好的材料
React.js中的组件状态的最佳实践
将React项目从ES5转换为ES6

  • 还有没有第三种方法来构造对象,作为功能性的“状态挂钩”?https://reactjs.org/docs/hooks-state.html我是本机新手,所以我可能是错的。 (2认同)
  • @djangofan,您好,我想暂时更新一下。感谢您将我推向这个方向。我添加了带有类字段的新速记和带有React钩子的`useState`。 (2认同)

Ali*_*eza 29

OK,最大的区别是,他们是从哪里来的开始,所以constructor你在JavaScript类的构造函数,另一边,getInitialState是部分lifecycleReact.

constructor 是你的课程初始化的地方......

构造函数

构造函数方法是一种用于创建和初始化使用类创建的对象的特殊方法.在类中只能有一个名为"constructor"的特殊方法.如果类包含多个构造函数方法,则将抛出SyntaxError.

构造函数可以使用super关键字来调用父类的构造函数.

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

设置初始状态

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

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

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

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

访问此处获取更多信息.

还创建了下面的图像,以显示React Compoenents的几个生命周期:

反应生命周期


小智 7

如果您正在使用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({

});
Run Code Online (Sandbox Code Playgroud)