API openweathermap.org. Как показывать погоду конкретного города, берущегося из массива?
Вот компонент, отвечающий за запросы на сервер:

Вот компонент отвечающий за рендер:
Что хочу получить: выбираю город из селектора - соответсвенно рендерится прогноз погоды по этому городу. Вопрос. Какой аргумент мне прописывать в getWeather()? city нельзя это просто весь массив. city[0] тоже, т.к. получает жестко привязанный элемент, мне то надо динамически. И второй вопрос. Как правильно реализовать логику в этом компоненте?
<div className="search_city">
<select name="select">
{city.map(item => <option value={item}>{item}</option>)}
</select>
</div>
Если я оставляю так, то получается незадействованный "tawn" из useState.
В общем не хватает знаний (или я просто сильно туплю), что бы дожать функционал, прошу помощи.
p.s.
Результат на выходе такой (не смотрите на стили потом доделаю).

Температуру, ветер и т.д. разбил на отдельные компоненты, вот пример:
@gaf, получается вот так:
const SearchCity = () => {
const {getWeather} = WeatherServise();
const city = [
{
"id": "833",
"name": "Ḩeşār-e Sefīd"
},
{
"id": '3245',
"name": "Taglag",
},
]
const [tawn, setTawn] = useState('Voronezh');
useEffect(() => {
updateId();
}, [])
const updateId = () => {
getWeather(tawn)
.then(onWeatherLoaded)
}
const onWeatherLoaded = (e) => {
setTawn(e.target.value);
}
return (
<div className="search_city">
<select value={tawn} onChange = {onWeatherLoaded} name="select">
{city.map(item => <option
key = {item.id}>
{item.name}</option>)}
</select>
</div>
)
}
В консоли получаю ошибку:Cannot read properties of undefined (reading 'value') Плюс я не понимаю куда и зачем мне нужно поднимать состояние, у меня все отрисовывается в этом компоненте
Ответы (1 шт):
Сначала: Тебе нужно почитать что такое "Контролируемые компоненты" - это ответит сразу на оба вопроса: как подгружать динамически и как правильно реализовать логику.
Потом: tawn - это ответ с данными о погоде. Значит должен его передавать туда, где ты отрисовываешь данные, тебе их надо поднять выше из компонента SearchCity, для этого почитай про "Подъём состояния". В будущем можешь почитать про "Контекст" - это более продвинутый подход к этой задаче.
И наконец: После того, как разберешься со всем предыдущим: тебе не нужно делать запрос getWeather() в Temperature, теперь можешь просто получить данные от родительского компонента через props и отрисовать их.
Обновление в ответ на изменение вопроса:
const SearchCity = () => {
const { getWeather } = WeatherServise();
const city = [
{
"id": "833",
"name": "Ḩeşār-e Sefīd"
},
{
"id": '3245',
"name": "Taglag",
},
]
const [town, setTown] = useState('Taglag') // Это имя текущего города и функция для его обновления. Начальное значение Taglag
useEffect(() => {
const getWeatherData = async () => {
const data = await getWeather(town) // Вернется массив с данными о погоде, тебе надо его передать таким компонентам, как: Temperature, чтобы они отрисовывали новые данные
}
getWeatherData()
}, [town]) // <- Запрос выполняем каждый раз, когда пользователь выбирает новый город
const handleChange = (e) => {
setTown(e.target.value)
}
return (
<div className="search_city">
<select value={town} onChange = {handleChange}> /* Это value значит какое значение сейчас выбрано */
{city.map(item => <option
key={item.id}
value={item.name} /* Это value значит вариант, который можно выбрать, не забывай указывать */
>
{item.name}</option>)}
</select>
</div>
)
}