反应-新道具传递给子组件后,Axios / Fetch / Ajax请求

时间:2018-09-08 11:10:12

标签: javascript reactjs components

我有两个部分,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;

2 个答案:

答案 0 :(得分:1)

您应使用当前ID调用check prev ID以避免递归更新。您只需确保仅在道具更改后才能从道具获得状态,

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

}

让我知道您的问题是否仍然存在

答案 1 :(得分:-1)

这可能是解决问题的一种方法,

首先,您必须更新getDerivedStateFromProps中的所有状态数据

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调用,并且您将进入无法预测的状态。尝试反跳。
  •