我是新来的反应者,我看到了一个类似的示例,但是并没有清楚地说明它们,我也不知道如何解决该问题。我有一个API,新数据已发布到API。
ComponentDidMount()
将首次从API初始化数据。
我浏览了文档,发现componentDiUpdate()
将始终在添加新数据后重新呈现页面。
到目前为止,这是我的代码:
constructor(props){
super(props);
this.state = {
newData: [],
dataApi: this.props.getAllData() //method that is using GET_ALL_DATA actions/reducers using fetch(get)
}
}
// it gets the data
componentDidMount() {
this.state.dataApi
}
componentDidUpdate(prevProps, prevState){
this.state.dataApi.then(data => {
if(prevProps.data != this.props.data) {
this.setState({newData: data});
}
}
}
ComponentDidUpdate()
错误:
无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。
如何解决此问题?通过在有人发出发布请求时从API获取新数据?谢谢
答案 0 :(得分:1)
componentDidMount()
生命周期方法仅在首次呈现组件时被调用一次。
在您的constructor()
中,您不需要对自己的状态做出承诺。相反,您可以删除dataApi
并直接调用该方法。在componentDidMount()
中,您将进行API调用。 API调用完成后,您可以使用this.setState()
。
每次更新prop或state值之一时,就会调用componentDidUpdate
方法。因此,当您冒险无限循环时,更新其中的状态是一个坏主意。
constructor(props){
super(props);
this.state = {
newData: [],
};
}
// it gets the data
componentDidMount() {
this.props.getAllData().then(data => {
this.setState({
newData: data,
});
});
}
答案 1 :(得分:0)
如果要在重新渲染之前挂接道具更改,请尝试挂接到componentWillReceiveProps。 componentWillReceiveProps将同步更新状态。
您组件componentDidMount中的还..代码什么也不做:)
// it gets the data
componentDidMount(){
this.state.dataApi}
尝试将其替换为
// it gets the data
componentDidMount() {
this.state.dataApi.then(data => {
this.setState({
newData: data,
});
});
}
答案 2 :(得分:0)
异步设置状态时(例如,在解决了诺言之后),重要的是确保您的组件仍处于挂载状态,否则,您可能会在未挂载的组件上设置状态(触发您得到的错误)。
为此,您需要设置某种标志(如下面的示例中的this.mounted
):
componentDidMount() {
this.mounted = true;
}
async componentDidUpdate() {
const data = await someAPICall();
if (this.mounted && !_.isEqual(this.state.data, data)) { // See comment below
this.setState({data});
}
}
componentWillUnmount() {
this.mounted = false;
}
此外,在将旧数据与新数据进行比较时,您需要执行深度比较(在上面的示例中,我使用lodash isEqual(...)
)。
浅表比较(即this.state.data !== data
)会比较每个对象的引用,无论实际数据如何,它们总是会有所不同,因此会遇到无限循环,因为setState()
将触发另一个componentDidUpdate()
,依此类推。
答案 3 :(得分:0)
解决了这个问题,谢谢大家: 该问题的解决方案将是:
this.state = {
allData: [],
isSubmitted: false
}
async componentDidUpdate(prevProps, prevState){
if(this.mounted && this.state.isSubmitted){
const allData = await this.props.getAllData();
this.setState({isSubmitted: false,
allData: allData.data })
}
componentDidMount(){
this.mounted=true
}
componentWillUnmount() {
this.mounted = false;
}
functionAddDataToApi(){
// some logic
this.setState({isSubmitted: true})
}