In a normal react project my router would look like this
I would have my app wrapped in a Component , and then I would have this
<Switch>
<Route path="/login" render={(props) => <LoginPage login={this.login} authed={this.state.isAuthenticated} {...props} />} />
<Route path="/" render={(props) => this.props.history.push("/login")} />
</Switch>
But I dont know how to simulate something similar in typescript . I currently have this
const App: React.FunctionComponent = () => {
return (
<Router>
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact pattern="/" />
<Route exactly component={Count} exact pattern="/count" />
</Switch>
</div>
</div>
</Router>
);
};
But it always redirects to main component. How could I do that an undefined route like /randomroute , would redirect to "/" , and how would I make the alternative route /count work?
EDIT: I have progressed a bit
import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";
interface ChildComponentProps extends RouteProps {
/* other props for ChildComponent */
}
const App: React.FunctionComponent<ChildComponentProps> = (props) => {
return (
<Router>
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route pattern ="/" render={() => props.history.push("/") } />
</Switch>
</div>
</div>
</Router>
);
};
export default App;
Problem now is that, history is inside the RouteComponentProps interface, while RouteProps interface contains render, and I cant use them at the same time, so im a bit lost
EDIT2: Trying this
interface RenderProps extends RouteProps {
/* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<HistoryProps & RenderProps>
Receiving in render
The expected type comes from property 'render' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Route> & Readonly & Readonly<...>'
When supposedly that interface is imported
Edit4:
I did this
import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps, withRouter } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";
interface RenderProps extends RouteProps {
/* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<RenderProps & HistoryProps> = (props) => {
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" {...props.history.push("/")} />
</Switch>
</div>
</div>
);
};
export default withRouter(App);
And wrapper the app component in index.tsx file into (browserouter)
Now im getting a
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops
Because of the props.history.push
I ended up doing this, but im waiting for better answers
import React from "react";
import { Route, Switch, RouteComponentProps, withRouter} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import Redirector from "./components/Redirect"
import "./App.css";
interface HistoryProps extends RouteComponentProps {
}
const App: React.FunctionComponent<HistoryProps> = (props) => {
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" exactly component={Redirector}/>
</Switch>
</div>
</div>
);
};
export default withRouter(App);
Redirect.tsx
import * as React from "react";
import { Redirect } from "react-router-dom";
const Redirector: React.FunctionComponent = () => {
return <Redirect to='/'/>;
};
export default Redirector
EDIT2: Probably a better approach
import React from "react";
import { Route, Switch, withRouter, Redirect} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import "./App.css";
const App: React.FunctionComponent = () => {
const renderFor404Routes = () => (<Redirect to='/'/>);
return (
<div className="main-content">
<div>
<Switch>
<Route exactly component={Main} exact path="/" />
<Route exactly component={Count} exact path="/count" />
<Route path ="/" exactly component={renderFor404Routes}/>
</Switch>
</div>
</div>
);
};
export default withRouter(App);
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