React Router with React 16.6 Suspense "Invalid prop `component` of type `object` supplied to `Route`, expected `function`."
Asked Answered
H

3

20

I'm using the latest version (16.6) of React with react-router (4.3.1) and trying to use code splitting using React.Suspense.

Although my routing is working and the code did split into several bundles loaded dynamically, I'm getting a warning about not returning a function, but an object to Route. My code:

import React, { lazy, Suspense } from 'react';
import { Switch, Route, withRouter } from 'react-router-dom';

import Loading from 'common/Loading';

const Prime = lazy(() => import('modules/Prime'));
const Demo = lazy(() => import('modules/Demo'));

const App = () => (
  <Suspense fallback={<Loading>Loading...</Loading>}>
    <Switch>
      <Route path="/" component={Prime} exact />
      <Route path="/demo" component={Demo} />
    </Switch>
  </Suspense>
);

export default withRouter(App);

The console warning is as follows: Warning: Failed prop type: Invalid prop `component` of type `object` supplied to `Route`, expected `function`.

A normal import would return a function, but the dynamic import with lazy() is returning an object.

Any fixes for this?

Henka answered 26/10, 2018 at 11:37 Comment(2)
That's odd you could try something like <Route path="/" component={() => <Prime/>} exact />Support
@Support That completely breaks my app. Found this issue, seems to be a solution: github.com/ReactTraining/react-router/issues/6420Henka
F
26

Try using render prop instead of component

<Route path="/" render={()=> <Prime />} exact />
<Route path="/demo" render={()=> <Demo />} />
Fare answered 27/10, 2018 at 7:57 Comment(5)
Thanks! Solution: <Route exact path="/" component={props => <Prime {...props} />} />Henka
ronnyrr's solution worked for me. Also, I updated to the latest version of React, and React router (react-dom 16.6.3 - react-router-dom 4.3.1)Forehand
This is not a good solution because it will cause constant unmounting and remounting of these components if your redux connection is above this in the hierarchy.Geniality
So the best way is: javascript <Route exact path="/" render={props => <Prime {...props} />} /> In this case, you also received props inside the component.Agronomy
Using inline arrow function as an argument for component prop will cause a re-render on each route change, which may be problematic if you are nesting routes and relay on lifecycle methods in rendered subcomponents. I would go with the @tmvnty solution instead.Mapp
B
11

This will be fixed in react-router-dom version 4.4+ as this issue suggests

You can wait for the final release or if you don't want to change your code today, you can install the beta version now by yarn add react-router-dom@next

Belshin answered 28/11, 2018 at 10:48 Comment(1)
I can confirm that react-router-dom v5.0.0 solves this problem. v4.4.x seems to have been beta releses only before the major v5.0.0 release.Grille
O
0

I know this answer do not respond the original question, but as I have experienced a similar issue, maybe my solution will help another people.

My Error:

Failed prop type: Invalid prop `component` of type `object` supplied to "link", expected function.

Alike the accepted answer, this could be fixed with:

<Link to={'/admin'} title={'Log In'} component={props => <Button {...props} />} />
Oxycephaly answered 19/9, 2019 at 3:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.