Javascript React-Axios/Fetch/Ajax在新道具传递给子组件后请求

Javascript React-Axios/Fetch/Ajax在新道具传递给子组件后请求,javascript,reactjs,components,Javascript,Reactjs,Components,我有两个组件,App和Child。我的目标是,应用程序将id传递给Child,当Child作为道具接收到id时,我希望Child执行Axios/Fetch请求,然后用结果数据更新自己。我将接受任何为我提供示例应用程序/子源代码的答案,这些示例应用程序/子源代码将完成我的示例,或者提供我的见解,如果这确实可能是我试图实现的 我是一个新的反应 //App.js import React, { Component } from 'react'; import Child from './Child.j

我有两个组件,App和Child。我的目标是,应用程序将id传递给Child,当Child作为道具接收到id时,我希望Child执行Axios/Fetch请求,然后用结果数据更新自己。我将接受任何为我提供示例应用程序/子源代码的答案,这些示例应用程序/子源代码将完成我的示例,或者提供我的见解,如果这确实可能是我试图实现的

我是一个新的反应

//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;
import React,{Component}来自'React';
从“/Child.js”导入子项;
导入“/App.css”;
类应用程序扩展组件{
状态={
身份证号码:0
};
handleClick(){
这是我的国家({
id:this.state.id+1
});
}
render(){
返回(
将新id向下传递给子组件
);
}
}
导出默认应用程序;
//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;
import React,{Component}来自'React';
从“axios”导入axios;
类子扩展组件{
状态={
数据:空,
身份证号码:0
};
负载数据(q,cb){
axios.get()http://localhost:3000/foo?q=“+this.state.id)
。然后(结果=>{
// ?
//this.setState将重新触发更新并创建无限更新循环
})
.catch(错误=>{
console.log('错误:'+错误);
});
}
shouldComponentUpdate(下一步,上一步状态){
log('shouldComponentUpdate:nextProps='+JSON.stringify(nextProps)+',prevState='+JSON.stringify(prevState));
// ??
}
更新前获取快照(下一步,前一步){
log('getSnapshotBeforeUpdate:nextProps='+JSON.stringify(nextProps)+',prevState='+JSON.stringify(prevState));
// ?? 
}
静态getDerivedStateFromProps(下一步,上一步){
log('getDerivedStateFromProps:nextProps='+JSON.stringify(nextProps)+',prevState='+JSON.stringify(prevState));
返回{
id:nextrops.id
};
// ?? 
}
componentDidUpdate(){
log('componentdiddupdate');
}
render(){
返回(
data={this.state.data}
);
}
}
导出默认子对象;

您应该使用当前Id调用check prev Id以避免递归更新。你只需要确保只有当你的道具发生变化时,你才能从道具中获得状态

static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.id !== prevState.id) {
    return {
        id: nextProps.id
    };
 }
 return null;

}
如果您的问题仍然存在,请告诉我

这可能是解决您问题的一种方法, 首先,您必须更新getDerivedStateFromProps中的所有状态数据 对于
loadData
方法中的api调用,您可以使用aync/await从api调用返回数据 注:

  • 这不是完整的解决方案,因为在
    loadData
    中的api调用捕获任何错误时,您可能不想更新状态
  • 此外,由于您使用的是api调用,您可能希望限制向子级传递道具的时间,因为它们都会触发不同的api调用,并且您将进入不可预测的状态。试试去抖

componentdiddupdate()
中,比较
prevProps.id
this.state.id
。如果它们不同,请调用
loadData()
。(我也不知道你的电流怎么会产生无限循环?)。为了使其成为循环,
componentdiddupdate()
必须始终调用
loadData()
。但是,只有当
id
发生更改时,才会发生这种情况。这已经有7周了,你还在坚持这一点,甚至没有尝试我的建议吗?如果道具改变,状态得到更新,你会在ComponentDidUpdate中调用loadData为什么?它将调用setState,它将一次又一次地更新componentDidUpdate。不,您可以在componentDidUpdate中进行检查,以避免不必要的setState调用
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
}
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;
    }
}