React.lazy makes Route's proptypes fail
Closed this issue Β· 28 comments
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
Same thing with React.memo()
.
Did you also upgrade react-dom
to 16.6.0
? I had the same issues but this tweet from @gaearon to a similar issue solved it for me.
edit: Never mind, I see the package.json
now. The above fixed the issue for my case, but perhaps there is also something else going on.
edit2: I see, originally it was not rendering at all but now I still see the console errors. Ignore me π
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} />} />
@tylerwray The trick doesn't seem to work with Typescript since Lazy doesn't have proper typing and jsx elements must be explicitly defined as a jsx component.
This was fixed in beta.5.
It's still an issue if react-is
is resolved to 16.5.x
- took me a good hour to track that down.
If you want, I can create a PR to bump the dependency requirement, perhaps?
Here's a reproduction, forked from the original codesandbox in this issue: https://codesandbox.io/s/q3y66owkj6
Ah, sorry!
@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 )
@pierreferry if you go that path, the render
prop would be better.
Any updates? It would be a great gift for the new year for me :)
Same here, any updates?
Same. The render prop work around resolves the warning. Not sure why this issue is closed though. It needs a fix. Β―\_(γ)_/Β―
I resolve this warning by using render <Route exact path="/" render={() => <Home />} />
@willnew , as @pierreferry mentioned:
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 )
@vtereshyn I believe this is different :
- @willnew uses render prop
- @tylerwray uses component prop
I haven't tested render method yet :)
Another thing i haven't tested: using not-inline functions
const renderHome = () => <Home />;
<Route exact path="/" render={renderHome} />
@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
@willnew , oh, sorry, misunderstood.
Okay, but its really a trick, so, I will wait for new release from react-router.
@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
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...
I have the same in js code, but it not happen in ts.
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 ?
@prakashtsi works as expected. waiting for new release which is compatible with React.lazy to get rid of this code
I just fixed it with updating react-dom
to 16.6.3
.
So before this the react
version for my project is 16.6.3
and the react-dom
version is 16.4.1
. So I updated react-dom
too.