with starter react not component reactjs react-router react-router-redux react-router-v4

reactjs - starter - react with typescript or not



reaccion-router-dom con TypeScript (7)

Estoy tratando de usar el router de reacción con TypeScript. Sin embargo, tengo ciertos problemas al usar la función withRouter. En la última línea, estoy recibiendo un error bastante extraño:

Argument of type ''ComponentClass<{}>'' is not assignable to parameter of type ''StatelessComponent<RouteComponentProps<any>> | ComponentClass<RouteComponentProps<any>>''. Type ''ComponentClass<{}>'' is not assignable to type ''ComponentClass<RouteComponentProps<any>>''. Type ''{}'' is not assignable to type ''RouteComponentProps<any>''. Property ''match'' is missing in type ''{}’

El código parece:

import * as React from ''react''; import { connect } from ''react-redux''; import { RouteComponentProps, withRouter } from ''react-router-dom''; interface HomeProps extends RouteComponentProps<any> { } interface HomeState { } class Home extends React.Component<HomeProps, HomeState> { constructor(props: HomeProps) { super(props); } public render(): JSX.Element { return (<span>Home</span>); } } const connectModule = connect( (state) => ({ // Map state to props }), { // Map dispatch to props })(Home); export default withRouter(connectModule);


+1 por la respuesta de Ramón. Absolutamente puede obtener cobertura de tipo completo aquí. Para agregar un poco - agregué la llamada a withRouter.

interface FooProps extends RouteComponentProps<Foo> { foo: string; } const Foo = ({ history, foo }: FooProps) => <span/>; const RoutedFoo = withRouter(Foo);

mis dependencias

"@types/react-router-dom": "^4.3.0", "typescript": "^2.9.2",


Creo que es un problema de compilación de mecanografía mecanografiada, pero he encontrado una solución:

interface HomeProps extends RouteComponentProps<any>, React.Props<any> { }


Después de navegar por las definiciones de RouteComponentProps descubrí la interfaz RouteComponentProps , así que ahora modelo mis contenedores así.

type RouteParams = { teamId: string; // must be type string since route params } interface Props extends RouteComponentProps<RouteParams>, React.Props<RouteParams> { } type State = { players: Array<Player>; } export class PlayersContainer extends React.Component<Props, State>{}

ahora en la clase de componentes se puede acceder a los accesorios de ruta de esta manera: let teamid = this.props.match.params.teamId;


Este es un problema mecanografiado de Typescript. Ya que withRouter () proporcionará los accesorios de enrutamiento que necesita en el tiempo de ejecución, usted quiere decirles a los consumidores que solo necesitan especificar los otros accesorios. En este caso, podría usar una ComponentClass simple:

export default withRouter(connectModule) as React.ComponentClass<{}>;

O, si tuvieras otros accesorios (definidos en una interfaz llamada OwnProps) que quisieras transmitir, podrías hacer esto:

export default withRouter(connectModule) as React.ComponentClass<OwnProps>;

Hay un poco más de discusión here


Parece que tiene el uso correcto para aplicar los accesorios de emparejamiento, historial y ubicación a su componente. Me gustaría consultar en su directorio node_modules para ver qué versiones de react-router y react-router-dom tiene, así como también los módulos @types .

Básicamente tengo el mismo código que usted, y el mío está trabajando con las siguientes versiones:

{ "@types/react-router-dom": "^4.0.4", "react-router-dom": "^4.1.1", }


Puedes probar así:

export default class AppContainer extends React.Component<{}, {}> { render() { return ( <BrowserRouter> <div> <Route path="/" exact={true} component={Login as any} /> <Route path="/home" component={Home as any} /> </div> </BrowserRouter> ); } }


Yo uso un enfoque diferente para solucionar este problema. Siempre separo las diferentes propiedades (enrutador, regular y despacho), por lo que defino las siguientes interfaces para mi componente:

interface HomeRouterProps { title: string; // This one is coming from the router } interface HomeProps extends RouteComponentProps<HomeRouterProps> { // Add your regular properties here } interface HomeDispatchProps { // Add your dispatcher properties here }

Ahora puede crear un nuevo tipo que combine todas las propiedades en un solo tipo, pero siempre combino los tipos durante la definición del componente (no agrego el estado aquí, pero si necesita uno solo siga adelante). La definición del componente se ve así:

class Home extends React.Component<HomeProps & HomeDispatchProps> { constructor(props: HomeProps & HomeDispatchProps) { super(props); } public render() { return (<span>{this.props.match.params.title}</span>); } }

Ahora necesitamos conectar el componente al estado a través de un contenedor. Se parece a esto:

function mapStateToProps(state, ownProps: HomeProps): HomeProps => { // Map state to props (add the properties after the spread) return { ...ownProps }; } function mapDispatchToProps(dispatch): HelloDispatchProps { // Map dispatch to props return {}; } export default connect(mapStateToProps, mapDispatchToProps)(Hello);

Este método permite una conexión completamente mecanografiada, por lo que el componente y el contenedor están completamente tecleados y es seguro refactorizarlo. Lo único que no es seguro para la refactorización es el parámetro en la ruta que se asigna a la interfaz HomeRouterProps .