I have a component which always needs to be rendered, but should only be visible if no routes have been matched (<Iframe isVisible={ifNoRoutesMatched} />).
So far I didn't find a nice way to check if that is the case. I went down this horrendous route of setting a variable to state with component wrappers but there must be a better way!? Also this needs withRouter and PureComponent otherwise the catchAllWrapper causes an infinite render loop:
class App extends PureComponent {
state = {
routeMatched: false,
}
catchAllWrapper = () => {
this.setState({ routeMatched: false });
return null;
}
routeWrapper = (RouteComponent) => {
const RouteWrapper = (props) => {
this.setState({ routeMatched: true });
return <RouteComponent {...props} />;
};
return RouteWrapper;
}
render() {
return (
<div className="App">
<Navigation />
<Switch>
<Route path="/chat" component={this.routeWrapper(Chat)} />
...more routes...
<Route component={this.catchAllWrapper} />
</Switch>
<Iframe isVisible={!this.state.routeMatched} />
</div>
);
}
}
export default withRouter(App);
I would rather have a manual array of route strings compare against than add this complexity!
this.props.match only has info on the route it matched INSIDE the matching component so it's pretty useless.
Is there are better way to do this?
Use case: it is an iframe which has a legacy app loaded on some routes, so it should not be destroyed and re-rendered between routes
Why not create a lightweight dummy component for the router to mount and unmount freely, then bind callback methods from your current class to its lifecycle events?
class Dummy extends Component {
componentDidMount() {
this.props.didMount();
}
componentWillUnmount() {
this.props.willUnmount();
}
render() {
return null;
}
}
class App extends Component {
state = {
showIframe: false,
}
cbDidMount = () => {
this.setState({ showIframe: true });
}
cbWillUnmount = () => {
this.setState({ showIframe: false });
}
render() {
return (
<div className="App">
<Navigation />
<Switch>
<Route path="/chat" component={Chat} />
{/* more routes */}
<Route render={() => <Dummy didMount={this.cbDidMount} willUnmount={this.cbWillUnmount} />} />
</Switch>
<Iframe isVisible={this.state.showIframe} />
</div>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With