如何在渲染我的React组件之前让axios获取请求等待

时间:2020-06-11 13:41:54

标签: javascript reactjs axios

我有以下代码:

import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import axios from "axios";

var config = {
  headers: {
    Accept: "application/json; odata=verbose",
    Authorization: "Bearer " + access_token,
  },
};

class Searchbar extends React.Component {
   async componentWillMount() {
    await axios.get(contracts, config).then((res) => {
      this.setState({ allContracts: res.data });
    });
  }
  render() {

    return (
      <div className="searchbar_wrapper">
        <Autocomplete
          freeSolo
          id="contract-search-bar"
          disableClearable
          options={contracts.map((option) => option.name)}
          onChange={(event, value) => {
          let selectedContractID =(value)
          }}
          renderInput={(params) => (
            <TextField
              {...params}
              label="Search"
              margin="normal"
              variant="outlined"
              InputProps={{ ...params.InputProps, type: "search" }}
            />
          )}
        />
      </div>
    );
  }
}
export default Searchbar;

我正在使用组件安装,因为我希望此函数在渲染组件之前先进行调用... axios调用将得到如下结果:

    results = [
      { name: "aaa" },
      { name: "bb" },
      { name: "cccc" },
    ];

结果将是500多个条目。

我遇到的问题是,在渲染组件时,它一直在说:

Cannot read property 'allContracts' of null

其原因是因为axios函数尚未完成获取结果...

请让我知道如何延迟渲染并等待axios首先获得结果然后继续

4 个答案:

答案 0 :(得分:2)

您基本上可以保持“正在加载”状态,并且在loadingtrue的情况下,渲染微调器或组件显示的内容。

答案 1 :(得分:1)

这将有所帮助。不需要 ComponentWillMount 。此外,还需要进行错误处理。

    state = {
      allContracts: null,
      error: false
    }

    componentDidMount(){
        axios.get(contracts, config)
         .then((res) => {
            this.setState({ allContracts: res.data });
        })
        .catch((err) => this.setState({error: true}))
    }

    render() {
      if(!state.allContracts && !this.state.error){
        return null; // add a spinner or something until the posts are loaded
      }

      if(this.state.error){
         return 'Something wrong happened...' // just an example of error
      }

     return // this will run after the posts are loaded
   }

答案 2 :(得分:0)

您可以像提到的@pirhan一样做到:

    constructor() {
        this.state = {
            isLoaded: false
        }
    }

    async componentDidMount() {
        const res = await axios.get(contracts, config);
        this.setState({ allContracts: res.data, isLoaded: true });
    }

    render() {
        if (!this.state.isLoaded) {
            return null /* or a loader/spinner */
        }

        return "I'm loaded ok."
    }

答案 3 :(得分:0)

管理加载状态并定义您的状态,如下所示:

category