当 api 由于道具更改需要多次调用时,应该使用哪个 ReactJS 生命周期函数?
Which ReactJS lifecycle function should be used when an api needs to called more than once due to a prop change?
我有一个名为 DeviceTab.js
的 parent 组件和一个名为 Graph.js
的 child 组件。 child 组件接收两个属性:name
和 span
。我需要在 Graph.js
中进行 api 调用,这取决于初始 name
或 span
道具以及它们何时从 parent 更新。现在,我在 componentDidMount()
中进行 api 调用,如下所示。然而,当道具得到更新时(我对这两个道具的状态也得到更新), api 不会被调用。我认为这是因为 componentDidMount()
只被调用一次。我应该使用另一种生命周期方法 and/or 将 api 调用移到其他地方吗?
在 Graph.js
中,我将这两个道具转换为这样的状态:
componentWillReceiveProps(props) {
this.setState({ device: props.device })
this.setState({ span: props.span })
}
这两个道具在我的 child 组件中的 componentDidMount()
中的 api 函数调用中用作参数:
componentDidMount(){
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
当 name
和 span
的 parent 道具在 parent 更新 组件,我在 child 组件中使用 componentDidUpdate()
来更新 child 的 name 和 span 状态如下:
componentDidUpdate(prevProps) {
if (this.props.name !== prevProps.name) {
this.setState({
name: this.props.name,
});
}
if (this.props.span !== prevProps.span) {
this.setState({
span: this.props.span,
});
}
}
编辑:
我听取了@Harmandeep Singh Kalsi 的建议并将 api 调用移至 componentDidUpdate
,但在加载数据时仍然遇到问题。这是更新后的方法:
componentDidUpdate(prevProps){
if (this.props.name !== prevProps.name) {
this.setState({ name: this.props.name})
// your api call goes here
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
}
if (this.props.span !== prevProps.span) {
this.setState({ span: this.props.span})
// your api call goes here
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
}
}
当我 console.log
api url 时,我看到使用从 parent 传递的初始 prop 值进行无限次调用,即 https://devices-api.com/name=test1&span=2
.当从 parent 传递更新的 prop 值时,还有另一组无限的 api 调用具有更新的值,即 https://devices-api.com/name=test2&span=4
。这会阻止我的组件加载来自 api 响应的数据。我的渲染方法是这样的:
if (this.state.devices.length > 0) {
return (
<Bar
data={this.state.devices}
/>
);
} else {
return (
<div className="sweet-loading">
<HashLoader css={override} size={150} color={"#42a315"} />
</div>
);
}
}
我只看到不停的 Hashloader 和半渲染图来回切换。
您应该改用 componentDidUpdate 有关详细信息,请查看此 link:https://reactjs.org/docs/react-component.html#componentdidupdate
示例:
componentDidUpdate(prevProps){
if(currentProps !== previProps){
<your api call goes here>
}
}
将 api 调用放入 componentDidUpdate(prevProps)
的条件语句之后。这个问题与条件有关。我必须检查 this.props.name
与 prevProps.name
的类型。我用 shallow-equal
来检查:
componentDidUpdate(prevProps){
if (!shallowEqualObjects(prevProps.name, this.props.name)) {
// api call here
}
}
我有一个名为 DeviceTab.js
的 parent 组件和一个名为 Graph.js
的 child 组件。 child 组件接收两个属性:name
和 span
。我需要在 Graph.js
中进行 api 调用,这取决于初始 name
或 span
道具以及它们何时从 parent 更新。现在,我在 componentDidMount()
中进行 api 调用,如下所示。然而,当道具得到更新时(我对这两个道具的状态也得到更新), api 不会被调用。我认为这是因为 componentDidMount()
只被调用一次。我应该使用另一种生命周期方法 and/or 将 api 调用移到其他地方吗?
在 Graph.js
中,我将这两个道具转换为这样的状态:
componentWillReceiveProps(props) {
this.setState({ device: props.device })
this.setState({ span: props.span })
}
这两个道具在我的 child 组件中的 componentDidMount()
中的 api 函数调用中用作参数:
componentDidMount(){
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
当 name
和 span
的 parent 道具在 parent 更新 组件,我在 child 组件中使用 componentDidUpdate()
来更新 child 的 name 和 span 状态如下:
componentDidUpdate(prevProps) {
if (this.props.name !== prevProps.name) {
this.setState({
name: this.props.name,
});
}
if (this.props.span !== prevProps.span) {
this.setState({
span: this.props.span,
});
}
}
编辑:
我听取了@Harmandeep Singh Kalsi 的建议并将 api 调用移至 componentDidUpdate
,但在加载数据时仍然遇到问题。这是更新后的方法:
componentDidUpdate(prevProps){
if (this.props.name !== prevProps.name) {
this.setState({ name: this.props.name})
// your api call goes here
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
}
if (this.props.span !== prevProps.span) {
this.setState({ span: this.props.span})
// your api call goes here
const {name, span} = this.state
fetch('https://devices-api.com/name=${name}&span=${span}')
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ devices : data });
});
}
}
}
当我 console.log
api url 时,我看到使用从 parent 传递的初始 prop 值进行无限次调用,即 https://devices-api.com/name=test1&span=2
.当从 parent 传递更新的 prop 值时,还有另一组无限的 api 调用具有更新的值,即 https://devices-api.com/name=test2&span=4
。这会阻止我的组件加载来自 api 响应的数据。我的渲染方法是这样的:
if (this.state.devices.length > 0) {
return (
<Bar
data={this.state.devices}
/>
);
} else {
return (
<div className="sweet-loading">
<HashLoader css={override} size={150} color={"#42a315"} />
</div>
);
}
}
我只看到不停的 Hashloader 和半渲染图来回切换。
您应该改用 componentDidUpdate 有关详细信息,请查看此 link:https://reactjs.org/docs/react-component.html#componentdidupdate
示例:
componentDidUpdate(prevProps){
if(currentProps !== previProps){
<your api call goes here>
}
}
将 api 调用放入 componentDidUpdate(prevProps)
的条件语句之后。这个问题与条件有关。我必须检查 this.props.name
与 prevProps.name
的类型。我用 shallow-equal
来检查:
componentDidUpdate(prevProps){
if (!shallowEqualObjects(prevProps.name, this.props.name)) {
// api call here
}
}