I have a couple of routes I want to show only when a certain condition is met. If this condition is met, and the routes are enabled navigating to them through the URL is not possible, and the Redirect always gets hit
constructor(props: {}) {
super(props);
this.state = {
configuration: new Configuration({}),
}
async function GetConfiguration() {
try {
var response = await fetch("/getconfiguration");
return await response.json();
}
catch (error) {
console.log(error);
}
}
async componentDidMount() {
...
var configuration = await GetConfiguration();
this.setState({ configuration: configuration });
...
}
render() {
...
<Router>
<Switch>
<Route exact path="/my-account">
<div className='dw-side-menu'></div>
...
</Route>
{this.state.configuration.shouldRoute && <Route exact path="/my-company"><div>my company</div></Route>}
{this.state.configuration.shouldRoute && <Route exact path="/user-management"><div>user management</div></Route>}
<Redirect to="/my-account" />
</Switch>
</Router>
...
}
The awkward thing is that, when I click on the Link
somewhere else on the page, the routing to, e.g. /my-company
, works - but not if I type the URL into the browser it only goes to the redirect, as if the routes are not there at all. Also if I hit refresh when on /my-company
I get redirected back to the my-account
. Without the conditions everything is working fine.
Without Redirect, entering the URLs and Refreshing the browser works as expected, just that I don't get redirected when a route is not recognized.
What am I doing wrong?
CodePudding user response:
As suspected in my comment, this.state.configuration.shouldRoute
is undefined
on first render.
One workaround for this would be to actually display a loading state until you have loaded the configuration, like so:
// in render(), before your other return
if(Object.keys(this.state.configuration).length === 0){
// config has not been loaded yet
return (<MyCoolLoadingComponent />)
}
If displaying a loading indicator before the config is loaded is an option, go with it. If it is not, you have to rethink your architecture.
CodePudding user response:
To make your code cleaner, with less bugs, put sections of codes into individual components. Then you could say:
class SideMenu extends component {
render(
<div className='dw-side-menu'></div>
...
)
}
class MyCompany extends component {
render(
<div>my company</div>
...
)
}
class UserManagement extends component {
render(
<div>user management</div>
...
)
}
render() {
...
<Router>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/my-account" component={MyAccount} />
<Route path="/my-company" component={MyCompany} />
<Route path="/user-management" component={UserManagement} />
<Redirect to="/my-account" />
</Switch>
</Router>
...
}
Cleaner code with less issues. Hope this helps. You can as well use some of the powerful features in react-router-dom; location, history and match. Thanks.