我有两个部分,App和Child。我的目标是将App的ID传递给Child,当Child将其作为道具接收时,我希望Child执行Axios / Fetch请求,然后使用结果数据自行更新。我将接受任何为我提供示例性App / Child源代码的答案,这些示例代码可以完成示例或提供我的见解,如果我实际上尝试实现这一点。
我是React的新手。
// App.js
import React, { Component } from 'react';
import Child from './Child.js';
import './App.css';
class App extends Component {
state = {
id: 0
};
handleClick() {
this.setState({
id: this.state.id + 1
});
}
render() {
return (
<div>
<Child id={this.state.id} />
<div>
<button onClick={this.handleClick.bind(this)}>Pass new id down to Child component</button>
</div>
</div>
);
}
}
export default App;
// Child.js
import React, { Component } from 'react';
import axios from 'axios';
class Child extends Component {
state = {
data: null,
id: 0
};
loadData(q, cb) {
axios.get('http://localhost:3000/foo?q='+this.state.id)
.then(result => {
// ?
// this.setState would retrigger update and create an infinite updating loop
})
.catch(error => {
console.log('error: ' + error);
});
}
shouldComponentUpdate(nextProps, prevState) {
console.log('shouldComponentUpdate: nextProps = ' + JSON.stringify(nextProps) + ', prevState = ' + JSON.stringify(prevState));
// ??
}
getSnapshotBeforeUpdate(nextProps, prevState) {
console.log('getSnapshotBeforeUpdate: nextProps = ' + JSON.stringify(nextProps) + ', prevState = ' + JSON.stringify(prevState));
// ??
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log('getDerivedStateFromProps: nextProps = ' + JSON.stringify(nextProps) + ', prevState = ' + JSON.stringify(prevState));
return {
id: nextProps.id
};
// ??
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
render() {
return (
<div>
<div>data = {this.state.data}</div>
</div>
);
}
}
export default Child;
答案 0 :(得分:1)
您应使用当前ID调用check prev ID以避免递归更新。您只需确保仅在道具更改后才能从道具获得状态,
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.id !== prevState.id) {
return {
id: nextProps.id
};
}
return null;
}
让我知道您的问题是否仍然存在
答案 1 :(得分:-1)
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.id !== prevState.id) {
// Returning this object is equivalent to setting state using this.setState
return {
id: nextProps.id
data: loadData(nextProps.id) // Something like this
};
}
return null; // Indicates no state change
}
loadData
方法中的api调用,您可以利用aync / await从api调用返回数据async loadData(id) {
try {
// Make your api call here
let response = await axios.get('http://localhost:3000/foo?q='+id);
return await response.json();
} catch(err) {
// catches errors both in axios.get and response.json
// Make sure to not update state in case of any error
alert(err);
return null;
}
}
注意:
- 这不是完整的解决方案,因为在
loadData
中的api调用捕获任何错误的情况下,您可能不希望更新状态。- 此外,由于您使用的是api调用,因此您可能希望限制将props传递给子级的时间,因为它们都会触发不同的api调用,并且您将进入无法预测的状态。尝试反跳。