Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I go about creating a react router in Typescript?

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

like image 858
mouchin777 Avatar asked Dec 30 '25 03:12

mouchin777


1 Answers

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);
like image 60
mouchin777 Avatar answered Jan 04 '26 15:01

mouchin777



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!