#javascript #node.js #reactjs #api #axios
Вопрос:
import React,{ useState, useEffect } from 'react'
import axios from 'axios'
const App = () => {
const [ countries, setCountries ] = useState([])
const [ search, setSearch ] = useState('')
const [ weather, setWeather ] = useState({})
const [ capital, setCapital ] = useState('')
const api_key = process.env.REACT_APP_API_KEY
const searchedCountries = countries.filter(country =>
country.name.common.toLowerCase().includes(search.toLowerCase()))
useEffect(() => {
axios
.get('https://restcountries.com/v3.1/all')
.then( response => {
setCountries(response.data)
})
},[])
useEffect(() => {
const url = `http://api.weatherstack.com/current?access_key=${api_key}amp;query=${capital}`
axios
.get(url)
.then(response => {
setWeather(response.data)
console.log('logged weather', response.data)
console.log('capital inside: ', capital)
})
},[search])
console.log(searchedCountries)
const handleSearch = (event) => {
setSearch(event.target.value)
if(searchedCountries.length === 1){
setCapital(searchedCountries[0].capital[0])
console.log('capital is set', capital)
}
else
setCapital('')
}
const handleShow = (event) => {
event.preventDefault()
setSearch(event.target.value)
}
if(searchedCountries.length > 10){
return(
<>
<div>
find countries
<input value = {search} onChange = {handleSearch} />
</div>
<p>Too many matches, specify another filter</p>
</>
)
}else{
if(searchedCountries.length === 1){
const languages = Object.keys(searchedCountries[0].languages)
console.log(typeof weather, weather)
return(
<>
<div>
find countries
<input value = {search} onChange = {handleSearch} />
</div>
<h1>{searchedCountries[0].name.common}</h1>
<p>capital {searchedCountries[0].capital[0]}</p>
<p>population {searchedCountries[0].population}</p>
<h2>languages</h2>
<ul>
{languages.map(language =>
<li key = {language}>{searchedCountries[0].languages[language]}</li>)}
</ul>
<img src= {searchedCountries[0].flags.png} alt= 'flag' />
<h2>Weather in {searchedCountries[0].capital[0]}</h2>
{/* <p><strong>temperature: </strong> {weather.current.temperature} Celcius</p> */}
</>
)
}else{
return(
<>
<div>
find countries
<input value = {search} onChange = {handleSearch} />
</div>
{searchedCountries.map( (country, index) => {
return(
<div key = {country.name.official}>{country.name.common}
<button onClick = {handleShow} value = {country.name.common} >show</button>
</div>
)
})}
</>
)
}
}
}
export default App
Например:
Я набрал «fin»,
Объект по-прежнему пуст.
После ввода «finl»,
Переменная погоды содержит данные о погоде в Хельсинки.(Мое ежемесячное использование достигло своего предела, поэтому погода.успех примера изображения имеет значение false.
Если я раскомментировал прокомментированную строку в своем коде, приложение выйдет из строя после того, как вы введете «fin».
Я хочу использовать данные в API погоды для этого приложения, не сталкиваясь с ошибками.
Можете ли вы помочь мне в решении этой проблемы. Я начинающий программист, изучающий react и взаимодействие react с API.
Спасибо вам за ваше понимание.
Ответ №1:
Вопрос
weather
является пустым объектом при первоначальном рендеринге:
const [ weather, setWeather ] = useState({});
Таким образом, попытка более глубокого доступа к объекту приведет к ошибке.
Пример:
weather // {}
weather.current // undefined
weather.current.temperature // error, cannot access X of undefined
Решение
- Вы можете либо указать допустимое начальное начальное состояние для того, к чему вы обращаетесь, чтобы при неопределенных/нулевых обращениях не возникала ошибка:
const [ weather, setWeather ] = useState({ current: {} });
Обратите внимание, что вам все равно может потребоваться выполнить следующее, чтобы убедиться, что у вас нет неопределенных/нулевых доступов при любом последующем рендеринге.
- Используйте необязательные предложения цепочки/защиты для защиты от неопределенных/нулевых обращений.
- Дополнительная Цепочка:
weather?.current?.temperature
- Охранные положения:
weather amp;amp; weather.current amp;amp; weather.current.temperature
- Дополнительная Цепочка:
Комментарии:
1. Кроме того, другая проблема заключается в том, что ввод, по-видимому, является задержкой в одном символе. это почему?
2. Обновления состояния реакции @spademarck обрабатываются асинхронно. Если вы регистрируете состояние сразу после его постановки в очередь, вы увидите состояние без обновления.
3. Что я могу сделать, чтобы избавиться от этой задержки? Будет ли лучше, если я не буду использовать useState для своих переменных?
4. @spademarck, какой ввод/состояние задерживается? Я снова изучаю ваш код и пытаюсь понять, почему у вас есть и
search
состояние, иcapital
состояние.search
является зависимостью дляuseEffect
крючка, но на нее нет ссылки, и вместоcapital
этого она используется в запросе GET. Можете ли вы уточнить, о чем конкретно вы говорите?5. У меня есть поиск, чтобы захватить значение входного элемента, и капитал, чтобы иметь значение основного значения для URL-адреса во втором эффекте использования.