gpt4 book ai didi

javascript - 从子组件调用时未设置 setState

转载 作者:行者123 更新时间:2023-11-30 19:40:02 26 4
gpt4 key购买 nike

我有一个简单的应用程序,它获取一些天气 JSON 并显示它。用户可以输入一个位置,也可以点击“幸运”按钮,这会随机获取一个城市。初始状态在 App.js 中设置

    this.state = {
error: '',
status: '',
queryString: 'london,gb',
queryID: '',
queryType: 'q',
cityData: cityData,
weatherData: {},
isLoaded: false
}

接下来,我有我的主 App 类,然后我有一个名为 gubbins 的子组件。我在应用渲染中调用它如下:

      <SearchForm
queryString={this.state.queryString}
handleChange={this.handleChange}
setQueryType={this.setQueryType}
setQueryID={this.setQueryID}
getWeatherData={this.getWeatherData}
/>

我在那里使用回调函数来设置查询类型(位置或 ID)。 App.js 中的回调函数之一的示例是:

  setQueryType = (queryType) => {
this.setState({
queryType: queryType
})
}

这在 JS 形式中使用:

 props.setQueryType(e.target.attributes.query.value)

现在,问题的症结在于:状态第一次没有更新,但第二次点击时更新了吗?事实上,其他变量,如在获取中设置的 queryString,直到第二次点击时才会设置。

App.js

import React, { Component } from 'react';
import './css/App.css';
import WeatherCard from './components/WeatherCard'
import Header from './components/Header'
import SearchForm from './components/SearchForm'
import cityData from './json/city.list'

const config = {
API: 'https://api.openweathermap.org/data/2.5/forecast',
API_KEY: process.env.REACT_APP_OPEN_WEATHER_MAP_API_KEY
}

class App extends Component {

constructor() {
super()
this.state = {
error: '',
status: '',
queryString: 'london,gb',
queryID: '',
queryType: 'q',
cityData: cityData,
weatherData: {},
isLoaded: false
}

this.getWeatherData()
}

getWeatherData = (searchValue="london,gb") => {
let URL
URL = config.API + '?' + this.state.queryType + '='
URL += this.state.queryType === 'q' ? searchValue : this.state.queryID
URL += '&units=metric&APPID=' + config.API_KEY

console.log(URL)

fetch(URL)
.then( result => result.json() )
.then (
(result) => {
if ( result.cod === '200') {
this.setState({
status: result.cod,
weatherData: result,
queryString: result.city.name,
isLoaded: true
})
} else {
this.setState({
status: result.cod,
error: result.message,
isLoaded: false
})
}
},
(error) => {
this.setState({
isLoaded: false,
error: error
})
}
)
console.log(this.state.queryString)
}

handleChange = (event) => {
const { name, value } = event.target
this.setState({
[name]: value
})
}

getWeatherCards = () => {
let cards = []
for (let i = 0; i < this.state.weatherData.cnt; i++) {
cards.push(
<WeatherCard
key={i}
weatherList={this.state.weatherData.list[i]}
/>
)
}
return cards
}

setQueryType = (queryType) => {
this.setState({
queryType: queryType
})
}

setQueryID = () => {
let randomID = Math.floor(Math.random() * this.state.cityData.length)
let randomCityID = this.state.cityData[randomID].id

this.setState({
queryID: randomCityID
})
}

getlocationForm = () => {
return(
<SearchForm
queryString={this.state.queryString}
handleChange={this.handleChange}
setQueryType={this.setQueryType}
setQueryID={this.setQueryID}
getWeatherData={this.getWeatherData}
/>
)
}

render = () => {
if (this.state.status !== '200') {
return (
<div className='App'>
<Header
status={this.state.status}
error={this.state.error}
/>
{this.getlocationForm()}
</div>
)
} else {
return (
<div className='App'>
{
this.state.isLoaded && (
<Header
cityName={this.state.weatherData.city.name}
countryName={this.state.weatherData.city.country}
status={this.state.status}
error={this.state.error}
/>
)
}
{this.getlocationForm()}
{
this.state.isLoaded && (
<div className='weather-cards'>
{this.getWeatherCards()}
</div>
)
}
</div>
)
}
}
}

export default App;

搜索表单.js

import React from 'react'

const SearchForm = (props) => {

let handleChange = function(e) {
props.handleChange(e)
}

let handleClick = function(e) {
e.preventDefault()

props.setQueryType(e.target.attributes.query.value)

if (e.target.attributes.query.value === 'id') {
props.setQueryID()
}

props.getWeatherData()
}

return (
<div>
<form className="search-form">
<input
type="text"
id="query"
name="query"
placeholder="Enter a location..."
onChange={handleChange}
/>
<button
type="submit"
query="q"
onClick={handleClick}
>
Submit
</button>
<button
type="submit"
query="id"
onClick={handleClick}
>
I'm feeling lucky...
</button>
</form>
</div>
)
}

export default SearchForm

最佳答案

在您的 App.js 构造函数中添加 this.setQueryType = this.setQueryType.bind(this)

该行会将 this 的上下文绑定(bind)到当前组件,因此当从子组件调用时,将更新父状态。

关于javascript - 从子组件调用时未设置 setState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55498144/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com