React Typescript: add location state to react router component

26,570

Solution 1

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.

Solution 2

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.

Solution 3

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

Solution 4

I benefitted from @Oliver Joseph Ash answer but somehow I did not have access to StaticContext perhaps because I use connected-react-router and it has no exported member but I did not dive deep.

I created a mock type like so:

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

This worked for me.

Solution 5

It works like a charm

const { valueX, valueY } = location.state as any;
Share:
26,570
peter
Author by

peter

Updated on January 01, 2022

Comments

  • peter
    peter over 2 years

    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.

  • pzaenger
    pzaenger over 4 years
    Maybe I miss the point, but how does this answer the question?
  •  aLLeXUs
    aLLeXUs over 4 years
    @pzaenger It does answer the question of how to fix compile failing, but as I said before, it is a temporary solution.
  • peter
    peter over 4 years
    Holy shit, you were actually almost spot on. In my Dockerfile, I added COPY yarn.lock /usr/src/app/ after I copied over the package.json, and that solved the issue
  • Prakhil TP
    Prakhil TP over 3 years
    I had the same issue. I accidentally use yarn for my old project, which was using npm as package manager. Then yarn creates a new lock file. Boom, issue raised. Thank you, I appreciate your help to solve this out.
  • ErikAGriffin
    ErikAGriffin about 3 years
    This seems a lot easier than using the third generic argument of RouteComponentProps to define the state type. Thank you
  • Spikatrix
    Spikatrix over 2 years
    Please add proper attribution to your answer. From what I can tell, this looks like you copied it from the transcription of a YouTube video without crediting the author (I edited the YouTube part out of your answer)
  • Admin
    Admin over 2 years
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
  • Admin
    Admin over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.