3
votes

React Typescript: ajoutez un état d'emplacement pour réagir au composant de routeur

J'ai un itinéraire normal

<Redirect
  to={{ pathname: '/login', state: { from: props.location } }}
/>

qui utilise RouteComponentProps de RouteComponentProps react-router-dom .

Étrangement, il n'y a pas eu de problèmes depuis longtemps avec ce composant, mais maintenant il ne parvient pas à se compiler sur travis-ci lorsque j'utilise history.push(location.state.from.pathname) disant que la Property 'from' does not exist on type '{}'.

J'ai défini cet état dans mon composant PrivateRoute qui est assez standard avec une redirection

function LoginPage(props: RouteComponentProps): React.ReactElement {...
}

Comment puis-je mettre à jour la saisie de l' location pour inclure un objet from avec pathname: string;

ÉDITER:

La solution était d'ajouter

COPY yarn.lock /usr/src/app/

dans mon Dockerfile après avoir copié le package.json.


4 Réponses :


2
votes

Il semble que vous n'utilisez pas de fichiers de verrouillage pour les packages. Je vous suggère de trouver un environnement de travail (dans l'image docker précédemment générée, ou de l'un des membres de l'équipe) et de générer package-lock.json (ou yarn.lock) là-bas. J'ai utilisé cette commande pour cela npm install --package-lock . Cela vous aidera pour la première fois jusqu'à ce que le problème soit complètement résolu.


4 commentaires

Peut-être que je rate le point, mais comment cela répond-il à la question?


@pzaenger Cela répond à la question de savoir comment réparer l'échec de la compilation, mais comme je l'ai déjà dit, c'est une solution temporaire.


Putain de merde, vous étiez en fait presque parfait. Dans mon Dockerfile, j'ai ajouté COPY yarn.lock /usr/src/app/ après avoir copié le package.json, et cela a résolu le problème


J'ai eu le même problème. J'utilise accidentellement du fil pour mon ancien projet, qui utilisait npm comme gestionnaire de paquets. Ensuite, yarn crée un nouveau fichier de verrouillage. Boom, problème soulevé. Merci, j'apprécie votre aide pour résoudre ce problème.



17
votes

Auparavant, la vérification de type était désactivée pour l'état de l'emplacement. Cela a changé avec https://github.com/DefinitelyTyped/DefinatelyTyped/issues/41674 .

Le type par défaut est unknown , mais vous pouvez le modifier à l'aide de génériques:

import { Location } from 'history';
import { ReactElement } from 'react';
import { StaticContext } from 'react-router';
import { RouteComponentProps } from 'react-router-dom';

type LocationState = {
    from: Location;
};

function LoginPage(
    props: RouteComponentProps<{}, StaticContext, LocationState>,
): ReactElement {
    props.history.push(props.location.state.from.pathname);
}


0 commentaires

2
votes

Vous pouvez utiliser le useLocation() fournissant un type générique, de cette façon vous pouvez remplacer le type unknown défini par défaut dans location.state .

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

interface stateType {
   from: { pathname: string }
}

const { state } = useLocation<stateType>();

console.log(state.from)

Cela devrait fonctionner correctement.


0 commentaires

0
votes

J'ai bénéficié de la réponse @Oliver Joseph Ash mais d'une manière ou d'une autre, je n'ai pas eu accès à StaticContext peut-être parce que j'utilise un connected-react-router et qu'il n'a pas de membre exporté mais je n'ai pas plongé profondément.

J'ai créé un type simulé comme ceci:

import { RouteComponentProps } from 'react-router-dom';

type LocationState = {
  // ... type of members passed to state
};

type MockType = {
  [key: string]: string | undefined;
};

type TypeWithLocationState = RouteComponentProps<MockType, MockType, LocationState>;

Cela a fonctionné pour moi.


0 commentaires