I have a problem with combining React lazy with my project that uses TypeScript and Redux. Here is my code:
// lazy-area.tsx
const LazyArea = ({text}: Props): JSX.Element => {
....
};
export const LazyArea = connect(
mapStateToProps,
mapDispatchToProps
)(LazyArea);
//Menu.tsx
import React, { lazy, Suspense } from 'react';
....
const lazyArea = lazy(() => import('./lazy-area'));
const Menu = ({
.....
}: Props): JSX.Element | null => {
return (
<Suspense fallback={LoadingView}>
<LazyArea />
</Suspense>
)
export const Menu = connect(
mapStateToProps,
mapDispatchToProps
)(Menu);
});
With this set up I get an error saying:
Type 'Promise<typeof import("/home/user/app/lazy-area")>' is not assignable to type 'Promise<{ default: ComponentType<any>; }>'.
Property 'default' is missing in type 'typeof import("/home/user/app/src/lazy-area")' but required in type '{ default: ComponentType<any>; }'.
I have tried solutions presented in:
TypeScript with React Lazy getting promise error
to add export as ComponentType<any>
and export as React.FC
to LazyArea export but error stays the same.
The solution presented in here removes the error but according to this the solution is def not best practice and "may kill optimizations and potentially result in infinite loop".
This error also goes away when using export default in LazyArea:
const LazyArea = connect(
mapStateToProps,
mapDispatchToProps
)(LazyArea);
export default LazyArea;
However I have read from some sources that using export default should be avoided.
Is there any good solution to get past this problem? Please inform if I have presented too little info about something. Thanks :)
I don't know why you think using default exports should be avoided :) I think it's just a convention that some teams have. So adding export default LazyArea;
is a valid way to deal with this. You won't have too many lazy modules anyway.
That's why the solution from React docs could also work where you just put that default export into its own file.
The other recommended approach is to change import code to convert it to default inline:
const LazyArea = React.lazy(() =>
import("./lazy-area").then((module) => ({
default: module.LazyArea,
}))
);
But that's seems like too much work for me :) So I created react-lazily which does what you would expect.
const { LazyArea } = lazily(() => import('./lazy-area'));
it's just a small wrapper around React.lazy
, but it allows you to have a really straight forward code, like that:
import { lazily } from 'react-lazily';
const { Component1, Component2 } = lazily(() => import('./Components'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With