[英]React: Is useEffect not guaranteed to run before the component renders?
I am trying to update some components in Gatsby.js
, based on what url path I am on. 我正在尝试根据我所处的url路径更新
Gatsby.js
一些组件。
I am using useEffect()
to make sure the components only update when location.pathname
(the part of the url after the domain) changes. 我正在使用
useEffect()
来确保组件仅在location.pathname
(域后的url部分)更改时才更新。
Here is the code: https://codesandbox.io/s/gatsbystarterdefault-290qv 这是代码: https : //codesandbox.io/s/gatsbystarterdefault-290qv
For some reason, useEffect
is not using the updated values of the location
prop (which is passed to the header
component, which in turn wraps every page). 由于某种原因,
useEffect
没有使用location
prop的更新值(它传递给header
组件,而header
组件又包裹每个页面)。
To reproduce, go to the CodeSandbox above and: 要重现,请转到上面的CodeSandbox并:
isHome when re-rendering Header
is true
while, isHome at NavItemLink
is false
isHome when re-rendering Header
为true
时,请参阅isHome when re-rendering Header
控制台语句,而isHome at NavItemLink
为false
Any idea why useEffect
does not get the latest value of location
? 知道为什么
useEffect
没有得到最新的location
值?
As stated in the React documentation on useEffect , useEffect
is "similar to componentDidMount
and componentDidUpdate
". 如关于useEffect的React文档中所述 ,
useEffect
“类似于componentDidMount
和componentDidUpdate
”。 Meaning yes, it runs only after the component renders. 意思是,它仅在组件呈现后运行。
You need to rerender the header component after changing navLinks
. 更改
navLinks
后,您需要重新呈现标题组件。 I recommend you do this by making navLinks
part of the component state with the useState
hook: 我建议你以这样做
navLinks
与组件状态的一部分useState
钩:
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])
I've created a fork of your code sandbox with the header component updated to use the useState
hook like shown above: https://codesandbox.io/s/gatsbystarterdefault-ftogs 我创建了一个代码沙箱的分支,更新了标头组件以使用
useState
所示的useState
钩子: https : useState
I would recommand using useMemo instead of useEffect or storing it inside state. 我建议使用useMemo而不是useEffect或将其存储在状态中。 useMemo will compute NavLinks only when it's dependency will change.
useMemo只有在依赖关系发生变化时才会计算NavLink。
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]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.