简体   繁体   English

在 componentDidMount() 中反应 Axios 调用

[英]React Axios call in componentDidMount()

I am trying to build a 'DataLoader' component that calls a Django Rest API via Axios and for testing purposes shows the results of the API call in an unordered list. I am trying to build a 'DataLoader' component that calls a Django Rest API via Axios and for testing purposes shows the results of the API call in an unordered list. The query terms are being generated in a parent component and passed via props.查询词在父组件中生成并通过道具传递。

Initially, the API is called with the query terms manufacturer & model_name both being blank.最初,调用 API 时查询术语制造商和型号名称都为空。 This part works, after the initial render I can see a unordered list that shows all the expected results.这部分有效,在初始渲染后,我可以看到一个显示所有预期结果的无序列表。

When the parent component passes new query terms via props to the 'DataLoader' component, the render() function is being executed, as I can see the当父组件通过 props 将新的查询词传递给“DataLoader”组件时,正在执行 render() function,我可以看到

 <ul><li>Data {this.props.selectedManufacturer}</li><li>Data {this.props.selectedModels}</li></ul>

part being executed and re-rendered correctly.正确执行和重新渲染的部分。

However, it seems that the componentDidMount() function with the Axios part is not being called again.但是,似乎没有再次调用带有 Axios 部分的 componentDidMount() function 。 How do I get React to call Axios again once new props have been passed from the parent component to the 'DataLoader' component?一旦新的道具从父组件传递到“DataLoader”组件,如何让 React 再次调用 Axios?

 import React from 'react'; import axios from 'axios'; import { getDefaultNormalizer } from '@testing-library/react'; class DataLoader extends React.Component { state = { cars: [] } componentDidMount(props) { axios.get(`http://127.0.0.1:8000/firstdraft/api/data?manufacturer=${this.props.selectedManufacturer}&model_name=${this.props.selectedModels}`).then(res => { const cars = res.data; this.setState({ cars }); console.log(this.state.cars) } ) } render(){ return( <> <h1>Top Selling Cars</h1> <ul>{this.state.cars.map(car => <li> {car.model_name}</li>)}</ul> <ul><li>Data {this.props.selectedManufacturer}</li><li>Data {this.props.selectedModels}</li></ul> </> ); } } export default DataLoader;

use componentDidUpdate and check if prevProps compared to current Props changed then run your axios call.使用 componentDidUpdate 并检查 prevProps 与当前 Props 相比是否发生了变化,然后运行您的 axios 调用。

 componentDidUpdatd(prevProps){ if(prevProps.selectedManufacturer.==this.props.selectedManufacturer){ //api call here } }

This is a typical use-case for componentDidUpdate() lifecycle method.这是componentDidUpdate()生命周期方法的典型用例。

Citing the docs :引用文档

componentDidUpdate(prevProps, prevState, snapshot)

componentDidUpdate() is invoked immediately after updating occurs.更新发生后立即调用 componentDidUpdate()。 This method is not called for the initial render.初始渲染不调用此方法。

Use this as an opportunity to operate on the DOM when the component has been updated.当组件更新时,将此作为对 DOM 进行操作的机会。 This is also a good place to do network requests as long as you compare the current props to previous props (eg a network request may not be necessary if the props have not changed).这也是进行网络请求的好地方,只要您将当前的 props 与以前的 props 进行比较(例如,如果 props 没有更改,则可能不需要网络请求)。

So, in your case:所以,在你的情况下:

componentDidUpdate(prevProps) {
  const shouldUpdateCars= 
    prevProps.selectedManufacturer !== this.props.selectedManufacturer
    || prevProps.selectedModels!== this.props.selectedModels

  if (shouldUpdateCars) {
    // fetch API and update state
  }
}

A full example would be:一个完整的例子是:

import React from 'react';
import axios from 'axios';
import { getDefaultNormalizer } from '@testing-library/react';

class DataLoader extends React.Component {
    state = {
        cars: []
    }

    fetchCars(manufacturer, models) {
         axios.get(`http://127.0.0.1:8000/firstdraft/api/data?manufacturer=${manufacturer}&model_name=${models}`)
      .then(res => {
        const cars = res.data;
        this.setState({ cars });
        console.log(this.state.cars)
        }
      )
    }

    componentDidUpdate(props) {
      const shouldUpdateCarsData = 
        prevProps.selectedManufacturer !== this.props.selectedManufacturer
        || prevProps.selectedModels!== this.props.selectedModels

      if (shouldUpdateCarsData ) {
        // fetch API and update state
        fetchCars(this.props.selectedManufacturer, this.props.selectedModels)
      }
    }
    
    render(){
        return(
            <>
                <h1>Top Selling Cars</h1>
                <ul>{this.state.cars.map(car => <li> {car.model_name}</li>)}</ul>
                <ul><li>Data {this.props.selectedManufacturer}</li><li>Data {this.props.selectedModels}</li></ul>
            </>
        );
    }
}

export default DataLoader;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM