react-router: React.lazy makes Route's proptypes fail

Hello,

The newly introduced React.lazy for easy code-splitting is making the Route component proptypes to fail with the warning :

Warning: Failed prop type: Invalid prop `component` of type `object` supplied to `Route`, expected `function`.

Version

react-router-dom: 4.4.0-beta.4 react: 16.6.0

Test Case

I took the official example from here : https://reactjs.org/docs/code-splitting.html#route-based-code-splitting

https://codesandbox.io/s/xp2nwl2qxw

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 58
  • Comments: 28 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@rnnyrk I just did the following for now 🤷‍♂️

const Home = React.lazy(() => import('./Home')

<Route exact path="/" component={props => <Home {...props} />} />

@pshrmn hey,when will you publish 4.4.0 version,this is a common problem。

This was fixed in beta.5.

Wait for a release 😃

@rnnyrk I just did the following for now 🤷‍♂️

const Home = React.lazy(() => import('./Home')

<Route exact path="/" component={props => <Home {...props} />} />

This trick does fix the error, but can have some side effect since it makes Home component re-render at every parent render. ( eg: if Home have componentDidMount )

Same thing with React.memo().

Any updates? It would be a great gift for the new year for me 😃

@vtereshyn it’s OK, I made a mistake that I didn’t explain in detail in my first comment. For others who worry about the case which @pierreferry mentioned, you can edit the demo code by entering <Route exact path="/" render={props => <Home {...props} />} /> and <Route exact path="/" component={props => <Home {...props} />} /> to see the paint flashing zone

@pierreferry if you go that path, the render prop would be better.

Ah, sorry!

@prakashtsi works as expected. waiting for new release which is compatible with React.lazy to get rid of this code

another option is to extend proptype definition for Route component prop (if not removed on build):

// react-router-dom-fix.js
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';

// suppress prop-types warning on Route component when using with React.lazy
// until react-router-dom@4.4.0 or higher version released
/* eslint-disable react/forbid-foreign-prop-types */
Route.propTypes.component = PropTypes.oneOfType([
  Route.propTypes.component,
  PropTypes.object,
]);
/* eslint-enable react/forbid-foreign-prop-types */

should not have any side effects…

This works for me. is it trustable @sunstorymvp ?

another option is to extend proptype definition for Route component prop (if not removed on build):

// react-router-dom-fix.js
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';

// suppress prop-types warning on Route component when using with React.lazy
// until react-router-dom@4.4.0 or higher version released
/* eslint-disable react/forbid-foreign-prop-types */
Route.propTypes.component = PropTypes.oneOfType([
  Route.propTypes.component,
  PropTypes.object,
]);
/* eslint-enable react/forbid-foreign-prop-types */

should not have any side effects…

@willnew , oh, sorry, misunderstood. Okay, but its really a trick, so, I will wait for new release from react-router.

@vtereshyn I made a small Demo, you can test with it with Paint flashing option enabled on Chrome developer tool, the Home component didn’t get re-rendered every time its parent’s state change. so I think its a workaround, though it is a trick