Загрузка данных с помощью useEffect - PullRequest
0 голосов
/ 27 марта 2020

Итак, у меня есть Маршрут, который загружает компонент панели мониторинга, и боковая панель с различными ссылками на этот компонент панели мониторинга. Я пытаюсь использовать useEffect для загрузки соответствующих данных из серверной части при загрузке компонента

const Dashboard = ({match}) => {
  const dispatch = useDispatch()
  const [loading, setLoading] = useState(true)
  const thing = useSelector(state => state.things)[match.params.id]

  const fetchData = async () => {
    setLoading(true)
    await dispatch(loadStuff(match.params.id))
    setLoading(false)
  }

  useEffect(() => {
    fetchData()
  }, [match]);

  return loading
     ? <div>Loading</div>
     : <div>{thing.name}</div>

}

Это работает достаточно хорошо для первой загрузки. Однако, когда я нажимаю NavLink на боковой панели, чтобы изменить {match}, thing.name взрывается. Я ожидаю, так как сопоставление является зависимостью от useEffect, что он перезапустит цикл загрузки и все приостановится, пока загрузка не будет завершена, вместо этого он пытается немедленно выполнить рендеринг, а вызов API вообще не выполняется. Если я удаляю thing.name, я вижу, что сделан вызов API и все работает.

Я продолжаю сталкиваться с этим, поэтому у меня возникает фундаментальное недопонимание того, как предсказуемо загружать данные с помощью приставки, когда компонент установлен. Что я тут не так делаю?

1 Ответ

0 голосов
/ 27 марта 2020

Обернули ли вы свой компонент withRouter реакционного маршрутизатора dom?

import React, { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';

const Dashboard = ({ match }) => {
  const dispatch = useDispatch()
  const [loading, setLoading] = useState(true)
  const thing = useSelector(state => state.things)[match.params.id]

const fetchData = async () => {
  setLoading(true)
  await dispatch(loadStuff(match.params.id))
  setLoading(false)
}

useEffect(() => {
  fetchData()
}, [match.params.id]);

return loading
   ? <div>Loading</div>
   : <div>{thing.name}</div>
}

export default withRouter(Dashboard);

Используйте match.params.id в useEffect, так как сравнение объекта (соответствия) не должно выполняться.

{} === {} /* will always be false and useEffect will be called every time 
             irrespective of match.params.id change. */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...