64 votes

réagir-routeur-dom avec Tapuscrit

Je suis en train d'utiliser réagir routeur avec des caractères d'imprimerie. Cependant, j'ai quelques problèmes à l'aide de withRouter fonction. Sur la dernière ligne, je suis assez bizarre d'erreur:

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 '{}'

Le Code ressemble à ceci:

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);

66voto

J'ai utiliser une autre approche pour résoudre ce problème. J'ai toujours de séparer les différentes propriétés (routeur, régulière et l'expédition), j'ai donc définir les interfaces suivantes pour mon composant:

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
}

Vous pouvez maintenant créer un nouveau type qui combine toutes les propriétés d'un seul type, mais j'ai toujours combiner les types lors de la définition du composant (je n'ai pas ajouter de l'état ici, mais si vous avez besoin d'un juste aller de l'avant). La définition de composant qui ressemble à ceci:

class Home extends React.Component<HomeProps & HomeDispatchProps> {
  constructor(props: HomeProps & HomeDispatchProps) {
    super(props);
  }

  public render() {
    return (<span>{this.props.match.params.title}</span>);
  }
}

Maintenant, nous avons besoin de câbler le composant à l'état par l'intermédiaire d'un conteneur. Il ressemble à ceci:

function mapStateToProps(state, ownProps: HomeProps): HomeProps => {
  // Map state to props (add the properties after the spread)
  return { ...ownProps };
}

function mapDispatchToProps(dispatch): HomeDispatchProps {
  // Map dispatch to props
  return {};
}

export default connect(mapStateToProps, mapDispatchToProps)(Hello);

Cette méthode permet une entièrement tapé de connexion, de sorte que le composant et l'emballage sont entièrement tapé et il est sûr de refactoriser le code. La seule chose qui n'est pas sans danger pour le refactoring est le paramètre de la route qui est mappé à l' HomeRouterProps interface.

20voto

carlosvin Points 148

Je pense que c'est un tapuscrit typings compilation problème, mais j'ai trouvé une solution de contournement:

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

6voto

Taylor Lafrinere Points 1840

C'est un Tapuscrit typings question. Depuis withRouter() va assurer le routage des accessoires vous avez besoin lors de l'exécution, vous souhaitez informer les consommateurs qu'ils ont seulement besoin de spécifier les autres accessoires. Dans ce cas, vous pouvez simplement utiliser une plaine ComponentClass:

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

Ou, si vous avez eu d'autres accessoires (définis par une interface appelée OwnProps) vous avez voulu passer, vous pourriez faire ceci:

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

Il y a un peu plus de discussion ici

6voto

Peter Benavides Points 43

Il semble que vous avez le droit d'utilisation appliquer le match, l'histoire et la localisation des accessoires à votre composant. Je voudrais vérifier dans votre node_modules annuaire de voir quelles sont les versions de react-router et react-router-dom vous avez, ainsi que le @types modules.

J'ai essentiellement le même code que vous, et la mienne est de travailler avec les versions suivantes:

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

4voto

SimperT Points 2381

Après la navigation sur le tapuscrit définitions que j'ai découvert l' RouteComponentProps interface de sorte que maintenant, je modèle mes conteneurs comme

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>{} 

maintenant, dans la classe de composant de la route des accessoires peut être accédé comme ceci: let teamid = this.props.match.params.teamId;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X