React:在组件渲染之前,useEffect 不能保证 运行 吗?
React: Is useEffect not guaranteed to run before the component renders?
我正在尝试更新 Gatsby.js
中的一些组件,基于我所在的 url 路径。
我正在使用 useEffect()
来确保组件仅在 location.pathname
(url 域之后的部分)更改时更新。
代码如下: https://codesandbox.io/s/gatsbystarterdefault-290qv
出于某种原因,useEffect
没有使用 location
属性的更新值(它被传递给 header
组件,后者依次包装每一页)。
要重现,请转到上面的 CodeSandbox 并:
- 点击第 2 页,然后再次返回第 1 页
- 请参阅
isHome when re-rendering Header
是 true
的控制台语句,而 isHome at NavItemLink
是 false
知道为什么 useEffect
没有得到 location
的最新值吗?
如 React documentation on useEffect 中所述,useEffect
为 "similar to componentDidMount
and componentDidUpdate
"。意思是,它仅在组件渲染后运行。
您需要在更改 navLinks
后重新渲染 header 组件。我建议您使用 useState
钩子使 navLinks
成为组件状态的一部分:
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])
我已经为您的代码沙箱创建了一个分支,其中更新了 header 组件以使用 useState
挂钩,如上所示:https://codesandbox.io/s/gatsbystarterdefault-ftogs
我建议使用 useMemo 而不是 useEffect 或将其存储在状态中。 useMemo 仅在其依赖性发生变化时才会计算 Nav Links。
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]);
我正在尝试更新 Gatsby.js
中的一些组件,基于我所在的 url 路径。
我正在使用 useEffect()
来确保组件仅在 location.pathname
(url 域之后的部分)更改时更新。
代码如下: https://codesandbox.io/s/gatsbystarterdefault-290qv
出于某种原因,useEffect
没有使用 location
属性的更新值(它被传递给 header
组件,后者依次包装每一页)。
要重现,请转到上面的 CodeSandbox 并:
- 点击第 2 页,然后再次返回第 1 页
- 请参阅
isHome when re-rendering Header
是true
的控制台语句,而isHome at NavItemLink
是false
知道为什么 useEffect
没有得到 location
的最新值吗?
如 React documentation on useEffect 中所述,useEffect
为 "similar to componentDidMount
and componentDidUpdate
"。意思是,它仅在组件渲染后运行。
您需要在更改 navLinks
后重新渲染 header 组件。我建议您使用 useState
钩子使 navLinks
成为组件状态的一部分:
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])
我已经为您的代码沙箱创建了一个分支,其中更新了 header 组件以使用 useState
挂钩,如上所示:https://codesandbox.io/s/gatsbystarterdefault-ftogs
我建议使用 useMemo 而不是 useEffect 或将其存储在状态中。 useMemo 仅在其依赖性发生变化时才会计算 Nav Links。
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]);