Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Typescript: add location state to react router component

I have a normal route

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

that uses RouteComponentProps from react-router-dom.

Strangely there were no issues for a long time with this component, but now it is failing to compile on travis-ci when I use history.push(location.state.from.pathname) saying Property 'from' does not exist on type '{}'.

I set this state in my PrivateRoute component that is pretty standard with a Redirect

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

How can I update the typing for location to include a from object with pathname: string;

EDIT:

The solution was to add

COPY yarn.lock /usr/src/app/

to my Dockerfile after I copied the package.json over.

like image 315
peter Avatar asked Jan 15 '20 13:01

peter


Video Answer


4 Answers

You can use the useLocation() hook providing a generic type, this way you can override the unknown type set by default in 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)

It should work fine.

like image 188
Francisco Baralle Avatar answered Sep 27 '22 22:09

Francisco Baralle


import * as H from "history";
const location: H.Location = useLocation();
like image 35
Sarah Esteves Avatar answered Sep 27 '22 21:09

Sarah Esteves


Previously, type checking was disabled for location state. That changed with https://github.com/DefinitelyTyped/DefinitelyTyped/issues/41674.

The type defaults to unknown, but you can change it using generics:

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);
}
like image 42
Oliver Joseph Ash Avatar answered Sep 27 '22 23:09

Oliver Joseph Ash


Looks like you do not use lock files for the packages. I would suggest you find a working environment (in the previously generated docker image, or from one of the team members), and generate package-lock.json (or yarn.lock) there. I used this command for it npm install --package-lock. It will help you for the first time until the issue will be solved completely.

like image 33
aLLeXUs Avatar answered Sep 27 '22 22:09

aLLeXUs