我使用反应两个月,反应将做构造函数,有时反应会做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构造函数
答案 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()
:
如果您想自己重制此图像,请注意Babel工具左侧已勾选的预设。
最后,您提到了this.state =
的替代方案是componentWillReceiveProps,但是替代方案实际上是我上面刚刚实现的。
请记住初始化状态和使用道具之间的区别。上面描述的所有内容都是constructor()
的初始化状态。
在React中,您会看到调用了不同的生命周期方法,但是通常来说,您将看到的大部分时间是constructor()
,当组件首次在屏幕上呈现时,它会自动被调用一次在首次启动组件时,您可能需要执行一次逻辑来执行初始数据加载和其他操作。
除了componentDidMount()
和componentDidMount()
外,您最常看到的其他生命周期方法是componentDidUpdate()
和componentDidUnmount()
,但这不是初始化状态的替代方法。
constructor()
函数是用于状态初始化的唯一生命周期方法,是的,它是生命周期方法,render()
方法也是如此。
答案 1 :(得分:0)
首先,Constructor
和ComponentWillReceiveProps
用于两个不同的目的。根据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
}
我希望你,我能够解释