Я изучаю React и пытаюсь написать асинхронный хук. Использование setResult
внутри useEffect
, похоже, не работает. Когда я попытался отобразить результат, ничего не было, поэтому я добавил несколько консольных журналов, чтобы увидеть, что происходит. Функция установки в хуке useState, похоже, ничего не делает. Я следил за этим видео для получения некоторого руководства, и мой код не слишком сильно отличается.
У меня есть следующий компонент:
import React, { useState, useEffect } from 'react'
const Search = () => {
const [search, setSearch] = useState('')
const [query, setQuery] = useState('')
const [result, setResult] = useState([])
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(
`https://api.spotify.com/v1/search?q=${encodeURIComponent(
query
)}&type=track`,
{
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + auth.access_token
}
}
)
const json = await response.json()
console.log({ json })
console.log(
json.tracks.items.map(item => {
return item.id
})
)
setResult(
json.tracks.items.map(item => {
return item.id
})
)
console.log({result})
} catch (error) {
console.log(error)
}
}
if (query !== '') {
fetchData()
}
}, [query])
return (
<div>
<input
value={search}
placeholder='Search...'
onChange={event => setSearch(event.target.value)}
onKeyPress={event => {
if (event.key === 'Enter') {
setQuery(search)
}
}}
></input>
<br />
{result.map(item => (
<h3 key={item}></h3>
))}
</div>
)
}
export default Search
От console.log ({ json })
я вижу, что ответ сервера выглядит нормально.
console.log(
json.tracks.items.map(item => {
return item.id
})
)
Приведенный выше вывод консоли также выглядит нормально.
setResult(
json.tracks.items.map(item => {
return item.id
})
)
console.log({result})
Почему result
пусто?
РЕДАКТИРОВАТЬ: Спасибо, Патрик и Талгат. Теперь я понимаю. Итак, когда я console.log
вне useEffect, я мог видеть, что result
установлен правильно. Затем я понял, что в моем рендере отсутствует ссылка на {item}
:
{result.map(item => (
<h3 key={item}>{item}</h3>
))}
Теперь я вижу идентификаторы, отображаемые на странице. Спасибо за вашу помощь.
setResult()
не обновляет состояние синхронно, он публикует обновление, которое происходит в запланированном микротике, и запускает повторный рендеринг компонента с обновленнымresult
. В следующий раз, когдаconst [result, setResult] = useState([])
будет оцениваться при повторном рендеринге, thenresult
будет содержать обновленный массив. - person Patrick Roberts   schedule 27.09.2019console.log(result)
за пределамиuseEffect
- person Talgat Saribayev   schedule 27.09.2019