构造器道具状态与简单状态

时间:2018-09-05 22:53:37

标签: javascript reactjs react-native

当我们可以简单地使用状态和创建对象而不是使用constructor(props){ super(props)

时,我就开始学习React。

现在,我看到许多仍在使用它们的库

class Master extends Component {
  constructor(props){
    super(props)

所以我的第一个问题是使用constructor (props) super(props)然后设置状态是否有优势?而不只是创建状态对象?

第二个问题,我想在自己制作的本机应用程序中实现react-native-slowlog

在整个代码中,我直接创建了state object而不是使用构造函数。

react-native-slowlog 的文档显示了这种使用方式

class Master extends Component {
  constructor(props){
    super(props)
    slowlog(this, /.*/)

    this.state = this.getDataSource(props)
    this.shouldComponentUpdate = shouldComponentUpdate.bind(this)
  }
...
}

他们在构造函数中调用slowlog(this, /.*/)的位置,所以我的问题是可以避免在这里使用构造函数吗?还是可以在创建slowlog(this, /.*/)的地方创建一个构造函数,然后在该构造函数之外创建状态对象?

class Master extends Component {
  constructor(){
    super() 
    slowlog(this, /.*/)
  } 


  state = {
    searchCoin: false
  }

3 个答案:

答案 0 :(得分:3)

  • 为什么使用constructor (props){}super(props)

唯一的原因是您想在构造函数React source code内部访问this

如果通过:

class MyComponent extends React.Component {
     constructor(props) {
         super(props)

         console.log(this.props)
         // goood
     }
 }

如果您没有通过,请致电超级

 class MyComponent extends React.Component {
     constructor(props) {
         super()

         console.log(this.props)
         // -> undefined

         // Props parameter is still available
         console.log(props)
         // good
     }

     render() {
         // No difference outside constructor
         console.log(this.props)
         // good
     }
 }

如果您不拨打电话

class MyComponent extends React.Component {
     constructor(props) {
           console.log(this)
         // undefined
     }
 }

总而言之,并非总是如此。

  • 在构造函数与外部中设置状态

那只是语法糖,因此没有区别。

构造函数每次安装仅获得一次调用,因此您想要执行不想在每个渲染中执行的操作。

答案 1 :(得分:2)

如果只需要定义constructor,则可以跳过显式的state,因为可以通过class fields proposal完成:

class Master extends Component {
  state = { searchCoin: false };
  ...

哪个是ES6的语法糖:

class Master extends Component {
  constructor(props){
    super(props);
    this.state = { searchCoin: false };
  } 
  ...

是否需要将state定义为类字段还是constructor主体的一部分,这是一个品味问题; class字段可输入的字符较少,因为它不包含constructor

还请注意

this.

是...的语法糖

class Master extends Component {
  constructor(){
    super() 
    slowlog(this, /.*/)
  } 

  state = { searchCoin: false }
  ...

类字段在class Master extends Component { constructor(){ super() this.state = { searchCoin: false }; slowlog(this, /.*/) } ... 之后和其他构造函数语句之前。如果预期super首先运行,则可能无法正常工作。

答案 2 :(得分:1)

仅在初始化状态或绑定函数时才需要使用构造函数。

  

如果您不初始化状态并且不绑定方法,那么您就不会   需要为您的React组件实现一个构造函数。 https://reactjs.org/docs/react-component.html#constructor

因此,对于链接到的库,您确实需要在构造函数中调用它。它既初始化状态,又绑定到shouldComponentUpdate函数。

但是,如果您不绑定任何内容,则总是可以像这样直接在属性上初始化状态...

打字稿

class Master extends React.Component<any, any> {
  public readonly state = { someKey: "Initial Value" };
}

JavaScript

class Master extends React.Component {
  state = { someKey: "Initial Value" };
}

我也不确定this.getDataSource(props)函数的作用,如果这只是slowlog提供的示例。但是不会在类属性AND上从构造函数初始化状态。因此,您可以像示例所示那样进行操作,也可以从componentDidMount函数中调用该函数。

class Master extends React.Component {
  // initialize your state
  state = { someKey: "Initial Value" };

  constructor (props) {
    super(props)
    slowlog(this /*, */);

    this.shouldComponentUpdate = shouldComponentUpdate.bind(this);
  }

  componentDidMount() {
    const nextState = this.getDataSource(this.props);
    this.setState(nextState);
  }
}

需要注意的是,如果getDataSource返回一个promise,则应该在组件安装时调用它,而不是从构造函数中调用。

  

如果您需要从远程端点加载数据,这是实例化网络请求的好地方。 https://reactjs.org/docs/react-component.html#componentdidmount