0

I have a couple of components that pass state to other components through using <Link to={{state:...}}>. This seems to work as expected in development and production, but does not pass during testing.

Router.test.tsx

test("renders DiffDashboardView with path '/{diffSetId}/diff/{diffId}'", async () => {
        const history = createBrowserHistory()
        const state = {
            foo: "bar",
        }

        const url = `/${diffSetId}/diff/${diffId}`
        history.push(url, state)
    
        render(
            <MemoryRouter initialEntries={[{ pathname: url, state: state }]}>
                <App/>
            </MemoryRouter>
        )
        
        await waitFor(() => {
            expect("bar").toBeInTheDocument() // Fails
        })
})

Router.tsx

function DiffRouter(props: ICommonProps): React.ReactElement {
    return (
        <div>
                <Switch>
                    <Route exact path="/">
                        <Redirect to="/local" />
                    </Route>
                    <Route exact path="/local">
                        <LocalDiffRoute />
                    </Route>
                    <Route path="/:diffSetId/diff/:diffId">
                        <DiffRoute isElectron={isElectron} />
                    </Route>
                    <Route exact>
                        <Unknown />
                    </Route>
                </Switch>
        </div>
    )
}

I also created a "middleman" route component to handle the passed state. This is where the behavior is wrong. During tests location is set to a global location object rather than an object of the type ILocationState as expected and state is always undefined. However, history.state at this point is an object {foo:'bar'}

DiffRoute.tsx

type ILocationState = {
    foo: string | undefined
}
function DiffUI(): React.ReactElement {
    const location = useLocation<ILocationState>() // x location = {pathname: '/local/diff/', search: '', hash: '', state: undefined, key: 'xshjkwgp'}

    return (
        <DiffDashboard
            fooProp={location.state?.foo ?? undefined}
        />
    )
}

fooProp in <DiffDashboard/> is undefined.

I've also tried using <Router/> and const history = createMemoryHistory() in my test, but then the navigation doesn't work this way (the pathname is always '/' regardless of what's pushed to history. Using MemoryRouter and createBrowserHistory is the only way I've been able to get the routing to work as expected. But now state is not being read from history in useLocation hook. Again, this only happens during testing. The behavior is as expected during development and production. I'm using the latest version ReactRouter V5

Any ideas on where I'm going wrong? Thanks

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Jordyn
  • 93
  • 10
  • The `MemoryRouter` isn't using the same `history` object you created. Also, why are you testing `react-router-dom` code? What are you trying to test? – Drew Reese May 02 '22 at 17:04
  • I added the state as apart of the initialEntries in the MemoryRouter component as well, so whatever it's using I expect it should have the same state object. And I'm testing that my routes navigate to the correct component views with state – Jordyn May 02 '22 at 17:15

0 Answers0