Search code examples
reactjstypescriptreact-routerreact-component

Typescript and React: Initializing RouteComponentProps members in React


I'm currently learning Typescript and React right now and am currently stuck on being able to access the 'match' member of props correctly. More specifically, I'm having trouble initializing the variables that are implemented from the RouteComponentProps interface.

To simplify things, I have the following 3 files and the corresponding components (path*) just render a header with text:

index.tsx

import React from 'react';
import ReactDOM from 'react-dom';

import App from './components/App';

ReactDOM.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>,
  document.getElementById('roots')
);

app.tsx

import React from 'react';
import {BrowserRouter as Router, Route, Switch, RouteComponentProps} from 'react-router-dom';

import Path1 from './Path1';
import Path2 from './Path2';
import Nav from './Nav'

class App extends React.Component<RouteComponentProps> {
  render(): JSX.Element{
    return (
      <Router>
        <div className="App">
          <Nav history={this.props.history} location={this.props.location} match={this.props.match}/>
          <Switch>
            <Route path="/" exact component={Home} name="Home"/>
            <Route path="/path1" exact component={Path1} name="path1"/>
            <Route path="/path2" exact component={Path2} name="path2"/>
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App

Nav.tsx

import React from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';

class Nav extends React.Component<RouteComponentProps>{
  render(): JSX.Element {
    return (
      <div className="Nav">
        {this.props.match.path}
        <ul className="NavLinks">
          <Link to="/">
            <li>Home</li>
          </Link>
          <Link to="/Path1">
            <li>Path1</li>
          </Link>
          <Link to="/Path2">
            <li>Path2</li>
          </Link>
        </ul>
      </div>
    );
  }
}

The basic idea is that upon clicking each link, the Nav component only updates the text at the top of the page based on whatever page the user is on. My reasoning behind putting the nav bar code where it is, is that it would save time in the future when adding more routes in.

Issue
My issue is that I need to pass the initial props in index.tsx, however I can't seem to find anything on how to initialize the props that are in the interface RouteComponentProps. Or if I'm doing it wrong (or anything else with the code) please tell me. I'm new when it comes to react/typescript and I would like to learn the right way the first time to not re-enforce bad habits.


Solution

  • Regarding doing it better, I would suggest using the functional components instead of class components.

    Functional components will also let you use react hooks. You can get location, history and match from hooks:

    interface MatchParams {
      name: string
    }
    
    const App = (): React.ReactElement => 
      const history = useHistory()
      const location = useLocation()
      const match = useRouteMatch<MatchParams>()
    
      return (
        <Router>
          <div className="App">
            <Nav history={history} location={location} match={match} />