0
votes

I have simple application in Reactjs + type script. I'm trying to use the BrowserRouter from react-router-dom.

This is my code :

import * as React from "react"

import { Popular } from "./popular"

import { BrowserRouter as Router, Route } from "react-router-dom"

export interface AppProp {

}

export interface AppState {

}
export class App extends React.Component<AppProp , AppState > {

    render() {
        return (

            <div className='container'>
                <Router>
                    <Route path='/popular' component={Popular} />
                </Router>
            </div>
        )
    }
}

export default App

I'm geting the following errors:

ERROR in [at-loader] ./node_modules/@types/react-router-dom/index.d.ts:55:25 TS2314: Generic type 'Component' requires 2 type argument(s).

ERROR in [at-loader] ./src/components/app.tsx:25:18 TS2604: JSX element type 'Router' does not have any construct or call signatures.

I search at google but nothing help.

someone has an idea ?

BR Nadav

2
you need to pass a history object to BrowserRouter - Jude Niroshan
I usually didn't use <div> before the <Router> or can you try to clear the className ? - Hana Alaydrus
Hi ,Thanks for your response even if the route is before the div still error is appear. - Nadav Dolinsky

2 Answers

0
votes

It seems to be Typings problem,

If you are using TypeScript 2.4.1, make sure you are using those versions of @types react.

"@types/react": "15.0.35",
"@types/react-dom": "15.5.1",
0
votes

I was able to use BrowserRouter with typescript and was able to pass both the history prop and my redux props/thunks down to my components. The key was to use 'withRouter' at the app level. I also had to use the render property with "Route" to get my props down. I can now use "this.props.history.push("/url1")" and "this.props.history.replace("/url2")" in my components as well as my props and thunks. Also the spread notation rocks.

import { RouteComponentProps, withRouter,
         Switch, Route, Redirect } from 'react-router-dom'

interface AppProps {
  children?: any
  myAppStore: any
  myAppActions: any
};

class App extends React.Component<RouteComponentProps<{}> & AppProps>
{
  constructor(props: RouteComponentProps<{}> & AppProps) {
  super(props);
 }

render() {
  return (
    <div className="App">
      <AppNavBar {...this.props}/>
      <Switch>

        // This component gets both Router props and my props
        <Route path="/c1" default={true} exact={true} render={()=>{return( 
           <MyComponentOne {...this.props}/>)} } />

        // This component only gets Router props
        <Route path="/c2" {...this.props} exact={true} component={MyComponentTwo } />

        </Switch>
        <Redirect from="/" to="/c1"/>
      </div>
    );
  }
}

... Do redux stuff ..
// ApplicationProps and ApplicationActions are mapped redux props and thunks.

const connector = connect(ApplicationProps,ApplicationActions);
export default connector<any>(withRouter(App));

This is my index.tsx render

  <Provider store={MyStore}>
  <BrowserRouter basename="/">
  <App/>
  </BrowserRouter>
  </Provider>