javascript - React - Axios promise 未定义的未决值

标签 javascript reactjs webpack axios autosuggest

我正在尝试使用 React 构建一个天气应用程序,react-autosuggest 用于列出可用城市的下拉列表和获取 Axios 的 api。

应用程序.jsx

import React, { Component } from "react";
import CityWeather from './components/CityWeather';
import SearchWeather from './components/SearchWeather';




class App extends Component {

    constructor(props){
        super(props);
        this.state = {
            value: '',
            suggestedCities: [],
            cityWeatherData: [],
            currentWeather: [],
        }
    };

    handleCityWeatherData = (city) => {
        this.setState({
            cityWeatherData: city
        });
    };

    handleOnChange = (newValue) => {
        this.setState({
            value: newValue
        });
    }

    render() {

        // Finally, render it!
        return (
            <div>
                <SearchWeather suggestData={{value: this.state.value, suggestedCities: this.state.suggestedCities}} onSelectCity={this.handleCityWeatherData} onChange={this.handleOnChange}/>
                <CityWeather weatherData={this.state.cityWeatherData}/>
            </div>
        );
    }
}

export default App;

API.jsx

import Axios from "axios";

//local file
let cities = "./public/cities.json";


export default {
    getCities: function(){
        return  Axios.get(cities).then((res) => {
            console.log("from apis", res.data.cities);
            resolve(res.data.cities);
        }).catch((error) => {
            console.log("from apis.jsx", error);
            []
        });
    },
    getTest: function(){
        return 'hello';
    }
    //add api for weather
};

我在获取数据时遇到问题,所以在 SearchWeather.jsx 中我想使用函数 const cities = apis.getCities() 获取城市列表它从不同的文件中检索数据,Apis.jsxgetCities 下使用 Axios方法。错误发生在 api.getCities ,在控制台中显示 <promise> pending我得到一个未定义的 cities多变的。不知道该怎么做,我尝试添加 await之前getCitiesapi.jsx但什么也没做。我可以使用 fetch而不是 Axios但我想用 Axios并了解更多。我确定它必须在 const cities = apis.getCities() 中执行,但不确定如何去做,我想我需要使用 resolve 但不知道如何。新 react ,所以我确定我错过了一些东西。我们将不胜感激您的帮助!

搜索天气.jsx

import React, { Component } from "react";
import Axios from "axios";
import Autosuggest from 'react-autosuggest';
import apis from '../utils/apis';


const getSuggestions = (value) => {
    const inputValue = value.trim().toLowerCase();
    const inputLength = inputValue.length;


    const cities = apis.getCities().then((data) => {
        console.log(data);
        data;
    });

    console.log('calling from getSuggestions');
    console.log(cities); //this is undefined from const cities


    return inputLength === 0 ? [] : cities.filter(city =>

        city.name.toLowerCase().slice(0, inputLength) === inputValue
    );
};

// When suggestion is clicked, Autosuggest needs to populate the input
// based on the clicked suggestion. Teach Autosuggest how to calculate the
// input value for every given suggestion.
const getSuggestionValue = suggestion => suggestion.name;

// Use your imagination to render suggestions.
const renderSuggestion = suggestion => (
  <span>{suggestion.name}</span>
);

class SearchWeather extends Component {

    onChange = (event, { newValue }) => {
        this.props.onChange(newValue);
    };

    // Autosuggest will call this function every time you need to update suggestions.
    // You already implemented this logic above, so just use it.
    onSuggestionsFetchRequested = ({ value }) => {
        this.setState({
          suggestedCities: getSuggestions(value)
        });
    };

    // Autosuggest will call this function every time you need to clear suggestions.
    onSuggestionsClearRequested = () => {
        this.setState({
          suggestedCities: []
        });
    };

    renderSuggestionsContainer = ({ containerProps, children, query }) => {
        return (
            <div {...containerProps}>
                {children}
                <h5>I like showing up.</h5>
            </div>
        );
    };

    fetchCityWeather = (cityId) => {
        //fetching sample request
        Axios.get("/public/sampleWeather.json").then((response) => {
            if(response.status === 200){
                return response.data
            }
            else{
                console.log('fetchCityWeather - something went wrong');
            }

        })
        .catch((error) => {
            console.log(error);
        });
    };

    onSuggestionSelected = (event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) => {
        console.log(suggestion);
        console.log(method);

        if(method == 'click'){
            let cityId = suggestion.id;
            let data = this.fetchCityWeather(cityId);
            this.props.onSelectCity(data); //pass data to parent
        }
    };


    componentDidMount = () => {
        console.log('componentDidMount');
    }


    render(){
        const value = this.props.suggestData.value;
        const suggestedCities = this.props.suggestData.suggestedCities;

        // Autosuggest InputProps
        const inputProps = {
          placeholder: 'Type your city',
          value,
          onChange: this.onChange
        };

        return(
            <Autosuggest
                suggestions={suggestedCities}
                onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                getSuggestionValue={getSuggestionValue}
                renderSuggestion={renderSuggestion}
                inputProps={inputProps} 
                shouldRenderSuggestions = {(v) => v.trim().length > 0}
                renderSuggestionsContainer={this.renderSuggestionsContainer}
                onSuggestionSelected={this.onSuggestionSelected}
            />
        );
    }
}

export default SearchWeather;

注意:我将 api 调用放在不同的文件中只是为了组织目的,并希望保持这种方式,除非这样做不正确。

附加信息:

我改变了const cities对此:

const cities = apis.getCities().then((data) => {
        console.log("from getCities", data);
        return data;
    });

我在控制台中注意到以下顺序:

来自 console.log(cities)SearchWeather

Promise {<pending>}

来自 Apis.jsx console.log("from apis", res.data.cities); , 数据

from apis (4) [{..},{..}]

来自 SearchWeather , console.log("from getCities", data);

from getCities (4) [{..},{..}]

不知道这是否有帮助,但是 const cities被跳过然后返回并打印实际数据

最佳答案

Axios 无法像 let cities = "./public/cities.json"; 那样请求 URL

如果你把这个 json 文件放在 public 文件夹中,你可以像这样设置 URL

http://localhost:3001/public/cities.json

别忘了端口。这是对主机的 HTTP 请求,而不仅仅是读取本地文件。

关于javascript - React - Axios promise 未定义的未决值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52610611/

相关文章:

javascript - Twitter Bootstrap 警报更改类

javascript - 调用添加到函数原型(prototype)的函数

javascript - Aurelia JS - 在 Kendo UI slider 更改时运行函数?

javascript - 返回组件时如何重构&&()

webpack - 在 Jest 测试中使用 webpack 的工作加载器解析导入

css - 如何从 js 包中删除 css?

javascript - JSON.parse() 保持字符串编码

javascript - 错误: Javascript identifier already been declared inside switch when deconstructing variable

javascript - container prop在material-ui的Drawer组件中有什么作用

javascript - 无法使用 babel-loader 编译符号链接(symbolic link)包的 TypeScript