React:this.forceUpdate并通过react-router-dom Link组件传递状态

问题描述 投票:0回答:1

我已经解决了自己的问题,但我不知道发生了什么以及它为什么有效。

我有一个链接组件,可以链接到当前所在的同一页面,但针对不同的产品。因此相同的组件但显示不同的产品。

<Link to={directUrl} onClick={() => this.forceUpdate} state={{ urlPicture: picture }}>
(请注意是在子组件中,而不是它路由到自身的主组件中。)

由于路由到同一页面,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()}
时,我的状态确实可以正确通过链接。

我确实知道两者之间存在差异,并且 this.forceUpdate 是两者中较轻的一个,但据我所知,它应该刷新组件并更新其状态。我不明白为什么它还不够,老实说我不知道为什么它会这样工作。

提前致谢。

javascript reactjs react-router react-router-dom
1个回答
0
投票

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
来强制触发组件重新渲染,那么您就做错了事情。传递路由状态的组件应该在 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
钩子。

© www.soinside.com 2019 - 2024. All rights reserved.