react-constructor或componentWillRecevieProps

时间:2017-04-17 00:34:18

标签: reactjs constructor

我使用反应两个月,反应将做构造函数,有时反应会做componentWillRecevieProps。 例如:

renderGroups(){
    return this.props.groups.map( (group, i) => {
        return <PickerGroup key={i} {...group} onChange={this.handleChange} groupIndex={i} defaultIndex={this.state.selected[i]} />;
    });
}

这次写操作每次都会做PickGroup构造函数

2 个答案:

答案 0 :(得分:1)

它使您在此处的要求感到困惑,但是您提到React会收到一个constructor()函数,有时它会收到一个componentWillReceiveProps。

React中constructors()的目的是初始化状态。您在首次创建组件时初始化状态。之后,您可以在render()方法内使用状态,然后在将来的某个时刻,使用setState()更新该状态。

constructor()函数不同,您创建的每个React组件都需要render()方法,否则,React会引发错误。 constructor()函数不是React所必需的,但它是在基于类的组件中实现的,如下所示:

class App extends React.Component {
  constructor() {

   }

  // React says we have to define render()
  render() {
    window.navigator.geolocation.getCurrentPosition(
      (position) => console.log(position),
      (err) => console.log(err)
    );
    return <div>Latitude: </div>;
  }
};

constructor()函数特定于JavaScript语言,而不是React语言。

在JavaScript类中,constructor()函数是在创建该类的实例的任何时候都会被调用的第一个函数。

每次我们创建App组件的新实例并将其显示在屏幕上时,该constructor()函数将被自动并立即调用。

现在,要解决我认为是您的问题,这不是在React中初始化状态的唯一方法。

在我进入另一种初始化状态的方法之前,您应该知道,当我们定义构造函数方法时,它将自动由props对象调用,是的,这是相同的props功能组件和基于类的组件可能会看到的对象,如下所示:

class App extends React.Component {
  constructor(props) {

   }

  // React says we have to define render()
  render() {
    window.navigator.geolocation.getCurrentPosition(
      (position) => console.log(position),
      (err) => console.log(err)
    );
    return <div>Latitude: </div>;
  }
};

使用constructor(props)函数时,需要执行一个步骤,即添加super(props);。为什么我们必须添加它?

好吧,记住,我在这里谈论的是基于类的组件,请记住,作为基于类的组件,我们上面的App组件是在这里扩展或借用React.Component基类的功能

该基类本身具有一个constructor()函数,该函数内部具有一些代码,可以为我们设置react组件。

当我们在constructor()类中定义App函数时,从本质上讲,我们是在重写或替换constructor()类内部的React.Component函数,但是我们仍然需要确保React.Component constructor()函数内部的所有设置代码仍被调用。

因此,为了确保调用React.Component的{​​{1}}函数,我们调用constructor()super(props);是对父项super(props)函数的引用,仅此而已。

每次在基于类的组件中定义constructor()函数时,我们都必须添加super(props)

如果不这样做,将会看到一条错误消息,提示我们必须致电constructor()

定义此super()函数的全部原因是初始化我们的状态对象。

因此,为了初始化我的状态对象,我将在constructor()调用下面编写:

super(props);

这是我们的状态对象,最终将包含一些不同的数据,以及一些非常重要的属性,这些属性与放在一起的组件非常重要。

所以可以说我使用名为class App extends React.Component { constructor(props) { super(props); this.state = {}; } // React says we have to define render() render() { window.navigator.geolocation.getCurrentPosition( (position) => console.log(position), (err) => console.log(err) ); return <div>Latitude: </div>; } }; 的纬度属性来初始化我的状态,因为这是我正在处理的地理位置应用程序,所以现在我的初始化状态如下所示:

lat

我将class App extends React.Component { constructor(props) { super(props); this.state = {lat: null}; } 属性的值设置为lat,因为我还没有纬度,并且纬度值最终将是一个数字,在这种情况下,当您知道该值会是您还没有的数字,则可以将其默认为null

现在,假设我们在此应用上遇到错误,并且根本无法获取任何数据或状态。我们可以在状态中添加另一个名为null的属性,并将其默认为一个空字符串,如下所示:

errorMessage

现在,通过更改class App extends React.Component { constructor(props) { super(props); this.state = {lat: null, errorMessage: '' }; } 并将其重构为constructor(),然后完全删除this.state,来讨论state = {lat: null, errorMessage: '' };的替代项。

constructor()

这等效于使用class App extends React.Component { state = {lat: null, errorMessage: '' }; } 函数,我可以通过转到https://babeljs.io/并将上述代码添加到左面板并查看Babel如何将其转换为constructor()来证明这一点。无论如何,它会像下面这样将其转换回constructor()enter image description here

如果您想自己重制此图像,请注意Babel工具左侧已勾选的预设。

最后,您提到了this.state =的替代方案是componentWillReceiveProps,但是替代方案实际上是我上面刚刚实现的。

请记住初始化状态和使用道具之间的区别。上面描述的所有内容都是constructor()的初始化状态。

在React中,您会看到调用了不同的生命周期方法,但是通常来说,您将看到的大部分时间是constructor(),当组件首次在屏幕上呈现时,它会自动被调用一次在首次启动组件时,您可能需要执行一次逻辑来执行初始数据加载和其他操作。

除了componentDidMount()componentDidMount()外,您最常看到的其他生命周期方法是componentDidUpdate()componentDidUnmount(),但这不是初始化状态的替代方法。

constructor()函数是用于状态初始化的唯一生命周期方法,是的,它是生命周期方法,render()方法也是如此。

答案 1 :(得分:0)

首先,ConstructorComponentWillReceiveProps用于两个不同的目的。根据React DOCS

构造

  

在安装React组件之前,会调用它的构造函数。   在实现React.Component子类的构造函数时,您   应该在任何其他声明之前调用super(props)。除此以外,   this.props将在构造函数中未定义,这可能导致   错误。

     

构造函数是初始化状态的正确位置。如果你不这样做   初始化状态,你不会绑定方法,你不需要   为你的React组件实现一个构造函数。

componentWillReceiveProps:

  

在安装的组件之前调用componentWillReceiveProps()   收到新的道具。如果您需要更新状态以响应   prop更改(例如,重置它),您可以比较this.props   和nextProps并使用this.setState()执行状态转换   这种方法。

     

请注意,即使道具未更改,React也可以调用此方法,因此请确保比较当前值和下一个值(如果您   只想处理变化。父组件可能会发生这种情况   导致组件重新渲染。

     

在安装过程中,React不会使用初始道具调用componentWillReceiveProps。它仅在某些组件中调用此方法   道具可能会更新。

因此,一般情况下,当父组件发送不同的道具时,您可能希望在组件中调用take动作,在这种情况下,您将使用componentWillReceiveProps以及constructor来初始化状态道具。

在您的情况下,由于您正在使用map函数,因此每次调用renderGroups函数时都会反复安装相同的组件,因此每次调用constructor而不是componentWillReceiveProps }

我希望你,我能够解释