React Typescript: add location state to react router component

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.


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

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.


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.