如何在渲染react组件之前让axios获取请求等待?

问题描述 投票:0回答:1

我有以下代码。

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先得到结果,然后继续渲染。

javascript reactjs axios
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
投票

基本上可以保持一个 "加载 "状态,当 loadingtrue你可以像@pirhan所说的那样,在组件中渲染一个旋转器或其他东西。


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."
    }

0
投票

管理一个加载状态以及定义你的状态,就像这样:

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 {

       state = {   //define state here
          allContracts: []
        }
       async componentDidMount() {
        await axios.get(contracts, config).then((res) => {
          this.setState({ allContracts: res.data });
        });
      }
      render() {

        return (
          <div className="searchbar_wrapper">
          {   allContracts.length > 0 ?  //wait for data - manage loading state
            <Autocomplete
              freeSolo
              id="contract-search-bar"
              disableClearable
              options={allContracts.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" }}
                />
              )}
            />
          : <h1>Loading.. </h1>
          </div>
        );
      }
    }
    export default Searchbar;
© www.soinside.com 2019 - 2024. All rights reserved.