首页 > 解决方案 > 当我调用 axios 请求时如何让微调器显示

问题描述

当我将微调器放在组件上时,微调器正在显示,该组件确实具有内部 setTimeOut 方法的 mount 方法。但是,我希望 Soinner 在页面上没有内容时显示,只有在 thge axios 请求完成加载后,它才会显示页面内容而不是加载指示器。我已将 this.state.loaded 作为默认值设置为 false。当用户点击提交时,axios 请求正在处理并触发 setState 的加载为 true。

我尝试过条件渲染,例如

{this.state.loaded && }

this.setState({loaded: false }, () => { axios.get( https://www.food2fork.com/api/searchkey=${API_KEY3}&q=${this.state.name}) .then(result => this.setState({loaded: true, ingredients:res.data.recipes, })); });

//Recipes.js
import React from "react";
import axios from "axios";
import LoadingIndicator from "./loadingIndicator"

const API_KEY="f562842f0ff6b2d4fd24b9601aeb5e1b";
const API_KEY2="bfb76b78b11e7308cc3c027865a508dd";
const API_KEY3="726237903540780fabd8614c1fe4e75d"

class Recipes extends React.Component {

    state= {
        ingredients:[this.props.ingredients],
        loaded:false
    }




    handleChange=(e)=> {
        this.setState({
            [e.target.id]: e.target.value
        })
    }

    handleSubmit=(e)=> {
        e.preventDefault();
        console.log(this.state);
        axios.get(`https://www.food2fork.com/api/search?key=${API_KEY3}&q=${this.state.name}`)
            .then(res=> {
                console.log(res)
                this.setState({
                    ingredients:res.data.recipes,

                })
            })
    }

    render() {  


        const recipeList = this.state.ingredients.length >0? this.state.ingredients.map((ingredient)=> {
            return(
                <div key={ingredient.recipe_id}>
                    <img className="recipeImage" src={ingredient.image_url}/>
                    <p>{ingredient.title}</p>
                </div>
            )
        }) : <LoadingIndicator loaded={this.state.loaded}/>
        return(
            <div style={{padding:50}}>
            <form className="form" onSubmit={this.handleSubmit}>
                <label>Food Name or Ingredient: </label>
                <input
                id="name"
                onChange={this.handleChange}
                className="formText"
                 type="text"
                 placeholder="type in ingredient or recipe"
                 />
                 <button className="btn waves-effect waves-light" type="submit" name="action">Submit</button>
            </form>
                <div style={{marginTop:100}}>
                    {recipeList}
                </div>

            </div>
        );
    }

}


export default Recipes;





//LoadingIndicator.js

import React from 'react';
import { css } from '@emotion/core';
// First way to import
import { ClipLoader } from 'react-spinners';
// Another way to import. This is recommended to reduce bundle size

const override = css`
    display: block;
    margin: 0 auto;
    border-color: red;
`;

class LoadingIndicator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

    }
  }


  render() {
    return (
      <div className='sweet-loading' style={{marginTop:150}}>
        <ClipLoader
          css={override}
          sizeUnit={"px"}
          size={350}
          color={'#123abc'}
          loading={this.props.loading}
        />
        <h1>LOADING...</h1>
      </div> 
    )
  }
}

export default LoadingIndicator;

标签: javascriptreactjscomponentsaxios

解决方案


你的微调器逻辑有点不对,但是试试这个。Spinner 仅在 axios 请求中显示。

class Recipes extends React.Component {

    state= {
        ingredients:[this.props.ingredients],
        loading:false
    }

    handleChange=(e)=> {
        this.setState({
            [e.target.id]: e.target.value
        })
    }

    handleSubmit= (e)=> {
        this.setState({loading:true}) //starts spinner
        e.preventDefault();
        axios.get(`https://www.food2fork.com/api/search?key=${API_KEY3}&q=${this.state.name}`)
            .then(res=> {
                this.setState({
                    ingredients:res.data.recipes,
                }) // ***write catch function to catch error 
            }).finally(function(){
                 loading:false // stop spinner (in response/error)
            })
    }

    render() {  
        const recipeList = this.state.loading ?  // if loading is true, show loader
            <LoadingIndicator loaded={this.state.loaded}/> 
            :
            this.state.ingredients.length <= 0 ?  //  check if ingredients have length equals to zero, then show 
             'No ingredients available' 
              : 
              this.state.ingredients.map((ingredient)=> { // else loop and show each ingredients
                return(
                    <div key={ingredient.recipe_id}>
                       <img className="recipeImage" src={ingredient.image_url}/>
                       <p>{ingredient.title}</p>
                    </div>
                  )
              });
        return(
            <div style={{padding:50}}>
            <form className="form" onSubmit={this.handleSubmit}>
                <label>Food Name or Ingredient: </label>
                <input
                id="name"
                onChange={this.handleChange}
                className="formText"
                 type="text"
                 placeholder="type in ingredient or recipe"
                 />
                 <button className="btn waves-effect waves-light" type="submit" name="action">Submit</button>
            </form>
                <div style={{marginTop:100}}>
                    {recipeList}
                </div>

            </div>
        );
    }

}



推荐阅读