多次单击同一反应路由器链路时强制重新安装组件



我有一个路由页面,其中包含一个数据表,在组件挂载时获取数据。当我多次单击相同的 react-router-dom 链接(到上面的路由(时,似乎组件仅在路由更改时卸载(要渲染不同的组件(。

我希望在再次单击同一链接以获取新数据时强制重新挂载组件。在 react-router-dom Link 或任何其他 Link 组件中是否有任何选项或任何技巧来执行此操作?

我的示例代码在这里:https://codesandbox.io/s/react-router-9wrkz

我希望多次单击"关于"链接时将重新挂载"关于"组件

强制组件重新挂载的一种方法是更改keyprop(您可以使用Date.now()props.location.key(:

<Route
path="/about"
render={props => <About key={props.location.key} {...props} />}
/>

可以使用此方法进行渲染

componentWillReceiveProps(recievedProps) {
console.log("componentWillReceiveProps called");
if (
recievedProps &&
this.props &&
recievedProps.location &&
this.props.location &&
recievedProps.location.key &&
this.props.location.key &&
recievedProps.location.key !== this.props.location.key
) {
this.setState({ loading: true });
promise().then(result => {
this.setState({ value: result, loading: false });
});
}
}

供将来参考。除了上面提到的答案之外,我还需要调整一些东西,因为它们都没有按照我想要的效果。之前提到过 props 的比较,但由于键在对象(参考(中,它从未看到更新(您正在比较同一对象(。所以我通过将其保存为道具来跟踪。

我更喜欢使用组件DidUpdate,因为当您需要的可能只是更新某些元素时,您不会卸载和挂载整个组件,

对于此示例,您的组件确实需要使用 withRouter(( 进行链接,以便您可以访问路由属性。

// You cant use prevProps because object will be the same, so save it in component
private currentRouteLocationKey: string| undefined; 
public componentDidUpdate(): void {
const currentRouteKey = this.props.history.location.key;
// Compare keys so you only update when needed
if (this.currentRouteLocationKey !== currentRouteKey) {
// Add logic you want reset/ updated
this.refreshPage();
// Save the new key
this.currentRouteLocationKey = currentRouteKey;
}
}

这意味着有时我想强制重新安装,有时不想。我怎样才能实现这一点

这种方法怎么样? 它仅在 PUSH 上重新安装。 在替换时不重新装载。

https://codesandbox.io/s/react-router-forked-z8uco?file=/index.js

export function withRemountOnHistoryPush(Component) {
const DecoratedComponent = (props) => {
const [key, setKey] = React.useState(0);
const history = useHistory();
React.useEffect(() => {
return history.listen((_, action) => {
if (action !== "PUSH") return;
setKey((prev) => prev + 1);
});
}, [history]);
return <Component key={key} {...props} />;
};
return DecoratedComponent;
}

为什么不通过在组件中创建函数来强制重新加载 onClick:

remount(){
location.reload(true);
}

然后将 onClick 处理程序分配给链接:

<Link to="/your route" onClick = {this.remount}>

似乎工作正常,除非您反对重新加载页面。

最新更新