API 数据未被复制并存储到反应状态中,我该怎么做?
API data not being copied and stored into the state in react, how would I do this?
所以我是新来的,我有这个困境。我首先使用 axios 从 JSONPlaceholder 获取一个 "database",然后我可以将其存储在状态中,然后我想调用一个 API 来填充数据库中没有的缺失数据。只需快速 运行 代码,我正在使用 grabdata 从 JSONPlaceholder 中获取我需要的数据并将其放入数组中。然后我使用 callsetcycle,它调用 setcycle 方法,该方法应该循环遍历数组位置并获取我需要的数据,然后将其也存储在建议目的地数组中。我的问题是,信息没有被调用和存储,我不明白为什么。任何帮助将不胜感激。
export class App extends Component {
state = {
suggesteddestinations : [],
scheduleddestinations : [],
loaded: false
}
componentDidMount = () =>{
this.grabData().then(
this.callsetCycle()
)
}
callsetCycle = () =>{
if (this.state.suggesteddestinations.length>0){
console.log("2")
this.setCycle().then(
this.setState({
loaded: true
}))
}
}
grabData = () =>{
return new Promise(() => {
var url = "https://my-json-server.typicode.com/dharquissandas/weatherApp/suggesteddestinations";
Axios.get(url)
.then(contents => this.setState({ suggesteddestinations: contents.data}))
});
}
setCycle = () => {
return new Promise(() => {
var i
if (this.state.suggesteddestinations.length > 0){
for (i = 0; i < this.state.suggesteddestinations.length; i++) {
console.log("5")
this.apiCallCurrentWeather(this.state.suggesteddestinations[i].name, i)
this.apiCallForcast(this.state.suggesteddestinations[i].name, i)
}
}
});
}
apiCallCurrentWeather = async (name, pos) => {
const apicall = await fetch("http://api.openweathermap.org/data/2.5/weather?q="+name+"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
await apicall.json()
.then(data =>
this.setState(
this.setCurrentWeatherProperties(data, pos)
)
)
}
setCurrentWeatherProperties = (data, pos) => {
this.state.suggesteddestinations[pos].temp = data.main.temp.toString()
this.state.suggesteddestinations[pos].desc = data.weather[0].main
this.state.suggesteddestinations[pos].tempmax = data.main.temp_max.toString()
this.state.suggesteddestinations[pos].tempmin = data.main.temp_min.toString()
this.state.suggesteddestinations[pos].feelslike = data.main.feels_like.toString()
this.state.suggesteddestinations[pos].pressure = data.main.pressure.toString()
this.state.suggesteddestinations[pos].windspeed = data.wind.speed.toString()
}
apiCallForcast = async (name, pos) => {
const apicall = await fetch("http://api.openweathermap.org/data/2.5/forecast?q="+name +"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
await apicall.json()
.then(data =>
this.formatForcast(data, pos)
)
}
formatForcast = (data, pos) => {
this.state.suggesteddestinations[pos].dayone = data.list[4]
this.state.suggesteddestinations[pos].daytwo = data.list[12]
this.state.suggesteddestinations[pos].daythree = data.list[20]
this.state.suggesteddestinations[pos].dayfour = data.list[28]
this.state.suggesteddestinations[pos].dayfive = data.list[36]
}
render (){
console.log(this.state.suggesteddestinations)
console.log(this.state.loaded)
if (this.state.loaded) return null;
return(
<div>
<BrowserRouter>
<div className="container">
<Header />
{/* <Route path="/" render={(props) =>
<Home {...props} suggesteddestinations={this.state.suggesteddestinations} />
} /> */}
<Route path="/home" component = {Home} exact />
<Route path="/CurrentWeather/:id" component = {CurrentWeather} />
<Route path="/EventSelection/:id" component = {EventSelection} />
<Route path="/Schedule" component = {Schedule} />
</div>
</BrowserRouter>
</div>
)
}
}
代码中存在一些问题,State cannot be mutated 意味着 this.state 不能设置在 constructor.The 之外,其他问题是代码设计过度 :)
由于您正在学习 React,我建议您从 react documentation
了解状态管理/道具/组件生命周期方法
不错的尝试!
这是实际的重构代码:
import React,{Component} from 'react'
export default class StackApp60663913 extends Component {
state = {
suggesteddestinations : [],
scheduleddestinations : [],
loaded: false
}
componentDidMount = () =>{
this.grabData()
}
grabData = async () =>{
let suggestionsApi = "https://my-json-server.typicode.com/dharquissandas/weatherApp/suggesteddestinations";
let suggestionFetch = await fetch(suggestionsApi)
let suggestionData = await suggestionFetch.json()
for (let index = 0; index < suggestionData.length; index++) {
let city = suggestionData[index]
let weatherFetch = await fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city.name}&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b`)
let weatherData = await weatherFetch.json()
let {main,weather,clouds,wind,sys} = weatherData.list[0]
suggestionData[index].temp = main.temp.toString()
suggestionData[index].desc = weather[0].description
suggestionData[index].tempmax = main.temp_max.toString()
suggestionData[index].tempmin = main.temp_min.toString()
suggestionData[index].feelslike = main.feels_like.toString()
suggestionData[index].pressure = main.pressure.toString()
suggestionData[index].windspeed = wind.speed.toString()
}
this.setState({
suggesteddestinations : suggestionData,
loaded:true
})
}
render (){
console.log(this.state.suggesteddestinations)
return(
<div>
{this.state.loaded ?
<div>
{
this.state.suggesteddestinations.map((element)=>
<li>
ID-{element.id},Name-{element.name},Temp-{element.temp},Desc-{element.desc},TempMin-{element.tempmin},TempMax-{element.tempmax}
</li>)
}
</div> : <div>Loading Data...</div>
}
</div>
)
}
}
所以我是新来的,我有这个困境。我首先使用 axios 从 JSONPlaceholder 获取一个 "database",然后我可以将其存储在状态中,然后我想调用一个 API 来填充数据库中没有的缺失数据。只需快速 运行 代码,我正在使用 grabdata 从 JSONPlaceholder 中获取我需要的数据并将其放入数组中。然后我使用 callsetcycle,它调用 setcycle 方法,该方法应该循环遍历数组位置并获取我需要的数据,然后将其也存储在建议目的地数组中。我的问题是,信息没有被调用和存储,我不明白为什么。任何帮助将不胜感激。
export class App extends Component {
state = {
suggesteddestinations : [],
scheduleddestinations : [],
loaded: false
}
componentDidMount = () =>{
this.grabData().then(
this.callsetCycle()
)
}
callsetCycle = () =>{
if (this.state.suggesteddestinations.length>0){
console.log("2")
this.setCycle().then(
this.setState({
loaded: true
}))
}
}
grabData = () =>{
return new Promise(() => {
var url = "https://my-json-server.typicode.com/dharquissandas/weatherApp/suggesteddestinations";
Axios.get(url)
.then(contents => this.setState({ suggesteddestinations: contents.data}))
});
}
setCycle = () => {
return new Promise(() => {
var i
if (this.state.suggesteddestinations.length > 0){
for (i = 0; i < this.state.suggesteddestinations.length; i++) {
console.log("5")
this.apiCallCurrentWeather(this.state.suggesteddestinations[i].name, i)
this.apiCallForcast(this.state.suggesteddestinations[i].name, i)
}
}
});
}
apiCallCurrentWeather = async (name, pos) => {
const apicall = await fetch("http://api.openweathermap.org/data/2.5/weather?q="+name+"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
await apicall.json()
.then(data =>
this.setState(
this.setCurrentWeatherProperties(data, pos)
)
)
}
setCurrentWeatherProperties = (data, pos) => {
this.state.suggesteddestinations[pos].temp = data.main.temp.toString()
this.state.suggesteddestinations[pos].desc = data.weather[0].main
this.state.suggesteddestinations[pos].tempmax = data.main.temp_max.toString()
this.state.suggesteddestinations[pos].tempmin = data.main.temp_min.toString()
this.state.suggesteddestinations[pos].feelslike = data.main.feels_like.toString()
this.state.suggesteddestinations[pos].pressure = data.main.pressure.toString()
this.state.suggesteddestinations[pos].windspeed = data.wind.speed.toString()
}
apiCallForcast = async (name, pos) => {
const apicall = await fetch("http://api.openweathermap.org/data/2.5/forecast?q="+name +"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
await apicall.json()
.then(data =>
this.formatForcast(data, pos)
)
}
formatForcast = (data, pos) => {
this.state.suggesteddestinations[pos].dayone = data.list[4]
this.state.suggesteddestinations[pos].daytwo = data.list[12]
this.state.suggesteddestinations[pos].daythree = data.list[20]
this.state.suggesteddestinations[pos].dayfour = data.list[28]
this.state.suggesteddestinations[pos].dayfive = data.list[36]
}
render (){
console.log(this.state.suggesteddestinations)
console.log(this.state.loaded)
if (this.state.loaded) return null;
return(
<div>
<BrowserRouter>
<div className="container">
<Header />
{/* <Route path="/" render={(props) =>
<Home {...props} suggesteddestinations={this.state.suggesteddestinations} />
} /> */}
<Route path="/home" component = {Home} exact />
<Route path="/CurrentWeather/:id" component = {CurrentWeather} />
<Route path="/EventSelection/:id" component = {EventSelection} />
<Route path="/Schedule" component = {Schedule} />
</div>
</BrowserRouter>
</div>
)
}
}
代码中存在一些问题,State cannot be mutated 意味着 this.state 不能设置在 constructor.The 之外,其他问题是代码设计过度 :) 由于您正在学习 React,我建议您从 react documentation
了解状态管理/道具/组件生命周期方法不错的尝试!
这是实际的重构代码:
import React,{Component} from 'react'
export default class StackApp60663913 extends Component {
state = {
suggesteddestinations : [],
scheduleddestinations : [],
loaded: false
}
componentDidMount = () =>{
this.grabData()
}
grabData = async () =>{
let suggestionsApi = "https://my-json-server.typicode.com/dharquissandas/weatherApp/suggesteddestinations";
let suggestionFetch = await fetch(suggestionsApi)
let suggestionData = await suggestionFetch.json()
for (let index = 0; index < suggestionData.length; index++) {
let city = suggestionData[index]
let weatherFetch = await fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city.name}&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b`)
let weatherData = await weatherFetch.json()
let {main,weather,clouds,wind,sys} = weatherData.list[0]
suggestionData[index].temp = main.temp.toString()
suggestionData[index].desc = weather[0].description
suggestionData[index].tempmax = main.temp_max.toString()
suggestionData[index].tempmin = main.temp_min.toString()
suggestionData[index].feelslike = main.feels_like.toString()
suggestionData[index].pressure = main.pressure.toString()
suggestionData[index].windspeed = wind.speed.toString()
}
this.setState({
suggesteddestinations : suggestionData,
loaded:true
})
}
render (){
console.log(this.state.suggesteddestinations)
return(
<div>
{this.state.loaded ?
<div>
{
this.state.suggesteddestinations.map((element)=>
<li>
ID-{element.id},Name-{element.name},Temp-{element.temp},Desc-{element.desc},TempMin-{element.tempmin},TempMax-{element.tempmax}
</li>)
}
</div> : <div>Loading Data...</div>
}
</div>
)
}
}