我正在尝试使用React构建一个天气应用程序,react-autosuggest用于下拉列表列出可用的城市以及api获取Axios。
App.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;
Apis.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()
来获取城市列表,该函数从另一个文件{{ 1}},其中Apis.jsx
方法使用Axios。错误发生在getCities
中,在控制台中显示为api.getCities
,并且我对<promise> pending
变量未定义。不确定如何执行此操作,我尝试在cities
中的await
之前添加getCities
,但没有执行任何操作。我可以使用api.jsx
代替fetch
,但我想使用Axios
并了解更多信息。我确定它必须在Axios
中进行,但不确定如何进行,我想我需要使用resolve而不知道如何做。新来的反应,所以我确定我错过了一些东西。您的帮助将不胜感激!
SearchWeather.jsx
const cities = apis.getCities()
注意:我将api调用放在另一个文件中只是为了组织的目的,并且希望保持这种方式,除非这不是正确的方式。
其他信息:
我将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;
更改为此:
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) [{..},{..}]
被跳过然后返回并打印实际数据
答案 0 :(得分:1)
Axios无法请求类似let cities = "./public/cities.json";
的URL
如果将此json文件放在公用文件夹上,则可以设置类似的URL
http://localhost:3001/public/cities.json
不要忘记端口。这是对主机的HTTP请求,而不仅仅是读取本地文件。
答案 1 :(得分:0)
我注意到的第一件事是:
let cities = "./public/cities.json";
为了将文件读入代码,您必须使用require,如下所示:
let cities = require('./public/cities.json');
或如ES6
import cities from './public/cities.json'
任何能让您安心的东西。
我注意到的第二件事是,您在第一个承诺解决之后就返回了Axios(其中您根本不返回任何东西)。您可以这样:
getCities: function(){
return Axios.get(cities)
},
或者这个:
getCities: function(){
return Axios.get(cities).then(res => res.data.cities).catch(...) // return cities
},
这是为什么?
因为用.then
函数将其包装后,您正在解决它,那么无论它在其中返回的内容如何,都将成为另一个保证,使您可以将其与另一个(或者在您的情况下)链接起来:
apis.getCities().then((data) => {
const cities = data
});
如果使用我写的第一个,您将在此函数的data参数中返回响应。第二个将使您直接将城市变成数据。
编辑:
由于我误读了代码并且答案没有任何意义,所以我正在编辑答案:
为了获得异步诺言的响应,您必须向函数传递回调(或进行异步/等待),如下所示:
Apis.jsx
/**/
getCities : cb => Axios.get(cities).then(res => cb(res.data.cities))
/**/
SearchWeather.jsx
const getSuggestions = (value, cb) => {
/**/
apis.getCities().then(cities => {
/* your logic to filter cities goes here */
// return your filtered cities here
return cb(filteredCities)
});
}
class SearchWeather extends Component{
/**/
onSuggestionsFetchRequested = ({ value }) => {
const cb = suggestedCities => this.setState({ suggestedCities })
return getSuggestions(value, cb)
};
/**/
}
cb
(或回调)将在解决承诺后触发。