diff --git a/src/app/components/shared/Lazy/Lazy.js b/src/app/components/shared/Lazy/Lazy.js new file mode 100644 index 00000000..a6123e0a --- /dev/null +++ b/src/app/components/shared/Lazy/Lazy.js @@ -0,0 +1,87 @@ +// @flow strict +import React, { useState, useEffect } from 'react'; +import type { Node } from 'react'; + +type PropsType = { + loader?: *, + getModule: () => Promise<*>, + children: Node, +}; + +// type StateType = { +// AsyncModule: * +// }; + +const Lazy = ({ loader, getModule, ...rest }: PropsType) => { + // eslint-disable-next-line no-unused-vars + const [AsyncModule, setAsyncModule] = useState(null); + // eslint-disable-next-line no-console + console.log('rest', rest); + + useEffect(() => { + (async () => { + try { + const module = await getModule(); + // eslint-disable-next-line no-console + // console.log('module', module); + setAsyncModule(module.default); + // eslint-disable-next-line no-empty + } catch (err) { + // eslint-disable-next-line no-console + console.log('err', err); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (loader) { + return
...loading
; + } + + if (AsyncModule) { + // eslint-disable-next-line no-console + console.log('AsyncModule', AsyncModule); + return ; + } + + return null; +}; + +// class Lazy extends Component { +// state = { +// AsyncModule: null, +// }; + +// async componentDidMount() { +// // eslint-disable-next-line no-unused-vars +// const { getModule, ...rest } = this.props; +// try { +// const module = await getModule(); +// this.setState({ +// AsyncModule: module.default, +// }); +// return module; +// } catch (err) { +// return new Error(err); +// } +// } + +// render() { +// const { loader, ...rest } = this.props; +// if (loader) { +// return
...loading
; +// } +// const { AsyncModule } = this.state; +// // eslint-disable-next-line no-console +// console.log('AsyncModule', AsyncModule); +// if (AsyncModule) { +// return ( +// +// ); +// } + +// return null; +// } +// } + +export default Lazy; diff --git a/src/app/components/shared/Lazy/Lazy.test.js b/src/app/components/shared/Lazy/Lazy.test.js new file mode 100644 index 00000000..d7bebf1d --- /dev/null +++ b/src/app/components/shared/Lazy/Lazy.test.js @@ -0,0 +1,14 @@ +// @flow strict +import React from 'react'; +// $FlowFixMe +import { render } from '@testing-library/react'; + +import Lazy from './Lazy'; + +describe('Lazy', () => { + it('should have component\'s name as className', () => { + const { container } = render(); + const div = container.firstChild; + expect(div.className).toEqual('lazy'); + }); +}); \ No newline at end of file diff --git a/src/app/components/shared/LazyComponent/LazyComponent.js b/src/app/components/shared/LazyComponent/LazyComponent.js new file mode 100644 index 00000000..fcc5590d --- /dev/null +++ b/src/app/components/shared/LazyComponent/LazyComponent.js @@ -0,0 +1,32 @@ +// @flow strict +import React, { useState, useEffect } from 'react'; +import type { Node } from 'react'; + +type PropsType = { + getModule: () => Promise<*>, + children?: Node, +}; + +const LazyComponent = ({ getModule, ...rest }: PropsType) => { + const [AsyncModule, setAsyncModule] = useState(null); + + useEffect(() => { + (async () => { + try { + const module = await getModule(); + setAsyncModule(() => module.default); + } catch (err) { + throw new Error(`LazyComponent error: ${err}`); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (AsyncModule) { + return ; + } + + return null; +}; + +export default LazyComponent; diff --git a/src/app/components/shared/LazyComponent/LazyComponent.test.js b/src/app/components/shared/LazyComponent/LazyComponent.test.js new file mode 100644 index 00000000..1a89a901 --- /dev/null +++ b/src/app/components/shared/LazyComponent/LazyComponent.test.js @@ -0,0 +1,14 @@ +// @flow strict +import React from 'react'; +// $FlowFixMe +import { render } from '@testing-library/react'; + +import LazyComponent from './LazyComponent'; + +describe('LazyComponent', () => { + it('should have component\'s name as className', () => { + const { container } = render(); + const div = container.firstChild; + expect(div.className).toEqual('lazy'); + }); +});