Реакция: Гарантируется ли, что useEffect запускается до визуализации компонента? - PullRequest
3 голосов
/ 26 мая 2019

Я пытаюсь обновить некоторые компоненты в Gatsby.js, в зависимости от того, по какому пути я нахожусь.

Я использую useEffect(), чтобы убедиться, что компоненты обновляются только при изменении location.pathname (часть URL-адреса после домена).

Вот код: https://codesandbox.io/s/gatsbystarterdefault-290qv

По какой-то причине useEffect не использует обновленные значения location prop (который передается компоненту header, который, в свою очередь, переносит каждую страницу).

Для воспроизведения перейдите к CodeSandbox выше и:

  1. Нажмите на страницу 2, затем снова на страницу 1
  2. См. Консольные утверждения, что isHome when re-rendering Header - это true, а isHome at NavItemLink - false

Есть идеи, почему useEffect не получает последнее значение location?

Ответы [ 2 ]

3 голосов
/ 26 мая 2019

Как указано в документации React для useEffect , useEffect "похоже на componentDidMount и componentDidUpdate". Значение да, он запускается только после рендеринга компонента.

Вам необходимо повторно визуализировать компонент заголовка после изменения navLinks. Я рекомендую вам сделать это, сделав navLinks частью состояния компонента с помощью useState hook:

const [navLinks, setNavLinks] = useState([])

useEffect(() => {
    setNavLinks(
        nav.map((navItem, index) => (
            <NavItemLink
              key={navItem.name}
              name={navItem.name}
              to={navItem.path}
              isHome={location.pathname === withPrefix("/")}
            />
        ))
    )
}, [location.pathname])

Я создал ветвь вашей песочницы кода с обновленным компонентом заголовка, чтобы использовать хук useState, как показано выше: https://codesandbox.io/s/gatsbystarterdefault-ftogs

2 голосов
/ 26 мая 2019

Я бы рекомендовал использовать useMemo вместо useEffect или хранить его внутри состояния.useMemo будет вычислять NavLinks только тогда, когда изменится их зависимость.

const generateNavLinks = path => nav.map((navItem, index) => (
  <NavItemLink
    key={navItem.name}
    name={navItem.name}
    to={navItem.path}
    isHome={path === withPrefix("/")}
  />
));

const navLinks = useMemo(() => generateNavLinks(location.pathname), [location.pathname]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...