我已经解决了自己的问题,但我不知道发生了什么以及它为什么有效。
我有一个
Link
组件,它链接到当前所在的同一页面,但针对不同的产品。所以相同的组件但显示不同的产品。
<Link to={directUrl} onClick={() => this.forceUpdate} state={{ urlPicture: picture }}>
请注意
<Link>
位于子组件中,而不是它路由到自身的主组件中。
因为它路由到同一页面,所以
Link
不会自动刷新页面。为了解决这个问题,我添加了onClick={() => this.forceUpdate}
,但现在我的状态没有正确通过。我用其他组件中的以下代码行检查了这一点。
location = useLocation()
const [ firstImage, setFirstImage ] = useState(location.state?.urlPicture || null)
console.log(`here is ${mainPicture}`) //mainPicture is just a string
但是,当我将
onClick={() => this.forceUpdate}
替换为 onClick={() => window.location.reload()}
时,我的状态确实会正确地通过 Link
。
我确实知道 2 之间存在差异,并且
this.forceUpdate
是 2 中较轻的一个,但据我所知,它应该刷新组件并更新其状态。我不明白为什么它还不够,老实说我不知道为什么它会这样工作。
forceUpdate是一个函数,因此需要调用它才能产生任何效果。
不起作用:
onClick={() => this.forceUpdate} // <-- not invoked!!
应该有效:
onClick={() => this.forceUpdate()} // <-- invoked
或
onClick={this.forceUpdate} // <-- passed as click handler and invoked
这就是为什么你的
onClick={() => window.location.reload()}
代码确实确实有效,尽管它会重新加载整个应用程序,这很可能是不需要的行为。
也就是说,在几乎 100% 的情况下,如果您使用
forceUpdate
来强制触发组件重新渲染,那么您就做错了事情。 Link
可能正在重新渲染组件,但该组件似乎并未对路由状态更改做出“反应”。传递路由状态的组件应该在 React 组件生命周期内处理它。在这种情况下,将使用 React.useEffect
钩子将本地组件状态与传递的路由状态重新同步。
示例:
const { state } = useLocation();
const [firstImage, setFirstImage] = useState(state?.urlPicture || null);
useEffect(() => {
if (state?.urlPicture) {
setFirstImage(state.urlPicture);
}
}, [state]);
然而,通常认为将传递的状态/属性/等存储到本地状态是一种 React 反模式。直接在组件中使用这些值,必要时记住它们。
示例:
const { state } = useLocation();
const firstImage = state?.urlPicture || null;
const { state } = useLocation();
const firstImage = useMemo(() => state?.urlPicture || null, [state]);
事实上,每当您编写
useState
-useEffect
耦合时,您都应该只使用 useMemo
钩子。