React, fetch, Hooks. Как дождаться получения данных и перерисовать форму с учетом их?
Сразу говорю, что читал документацию по useEffect, но не нашел там объяснения, ну или не понял, хотя честно старался. На SOF есть похожие случаи, но ни один из них не помог.
Код с комментариями
const App = () => {
const [filter, setFilter] = useState('fast');//отслеживаем изменения filter
const [data, setData] = useState([]);//чтобы подгрузить по json данные data, отфильтровать по
//filter и перерисовать документ
//Задаем useEffect, который запускает загрузку данных 1. при первом рендере и 2. при изменении filter
useEffect(() => {
loadData();
}, [filter])
const loadData = () => {
///json запрос, получив данные устанавливаем новое значение
.then(data => setData(data))
}
//Задаем ф-ю, меняющую filter которая будет передана в компонент для установки на кнопке
const changeFilter = (filter) => {setFilter(filter)}
//Отрисовываем. Если data===[] то компонент сам заменит данные на заглушку, но если нет - отрисует данные
return (
<>
<Component data={data} changeFilter={changeFilter}/>
</>
)
}
Естественно, данные по запросу приходят когда уже все отрисовано с data===[]. И поскольку управляет перерисовкой только useEffect, а он не следит за изменением data, то ничего не перерисовывается. А если заставить его следить за data, то конечно будет бесконечный цикл запросов. Я уже сломал всю голову, но не понимаю как заставить приложение перерисовываться после получения данных. Используя классы и state тоже ничего не получилось. Знаю, что видимо очень просто, но никак не могу сообразить. Если кто-то подскажет в какую сторону копать, буду очень благодарен.
Ответы (1 шт):
перерисовку запускает не useEffect а set(что то) ... то есть setData(data) перересует компонент вопрос в другом а data точно присутствует?
вот рабочий пример с логикой React У тебя все в проядке проблема в осталных частях
export const Test = () => {
const [state,setState] = useState({
"userId":'',
"id":'',
"title":'',
"name": "",
"username": "",
})
const [filter,setFilter] = useState(false)
const forChangeLink = filter ? 'todos' : 'users'
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/${forChangeLink}/1`)
.then(response => response.json())
.then(data => setState(data))
},[filter])
return (
<div style={{backgroundColor:'black',color:'white'}}>
{state.userId}
<br />
{state.id}
<br />
{state.title}
<br />
{state.name}
<br />
{state.username}
<br />
<button style={{color:'black',background:'green'}} onClick={() => setFilter((prev) => !prev)}> button</button>
</div>
)
}