// App.js import React from 'react'; import LineChart from './LineChart'; import BarChart from './BarChart'; export default class App extends React.Component { // state = { showCharts: false }; // handleChange = () => { this.setState({ showCharts: !this.state.showCharts }); } render() { return ( <div> Show charts: <input type="checkbox" value={this.state.showCharts} onChange={this.handleChange} /> { this.state.showCharts ? <div><LineChart/><BarChart/></div> : null } </div> ); } }
// LineChart.js import React from 'react'; import {Stage, Layer, Line} from 'react-konva'; export default () => ( <Stage width={100} height={100}> <Layer> <Line stroke="green" points={[0, 0, 20, 90, 50, 20, 100, 100]}/> </Layer> </Stage> );
// BarChart.js import React from 'react'; import {Stage, Layer, Rect} from 'react-konva'; export default () => ( <Stage width={100} height={100}> <Layer> <Rect fill="red" width={20} height={20}/> <Rect fill="blue" x={50} width={20} height={60}/> </Layer> </Stage> );
// LineChartAsync.js import React from 'react'; export default class AsyncComponent extends React.Component { state = { component: null } componentDidMount() { // DOM require.ensure([], (require) => { // !! : // require(this.props.path).default; // , webpack // const Component = require('./LineChart').default; this.setState({ component: Component }); }); } render() { if (this.state.component) { return <this.state.component/> } return (<div>Loading</div>); } }
import LineChart from './LineChart';
import LineChart from './LineChartAsync';
new webpack.optimize.CommonsChunkPlugin({ children: true, async: true, }),
// AsyncComponent.js import React from 'react'; export default class AsyncComponent extends React.Component { state = { component: null } componentDidMount() { this.props.loader((componentModule) => { this.setState({ component: componentModule.default }); }); } renderPlaceholder() { return <div>Loading</div>; } render() { if (this.state.component) { return <this.state.component/> } return (this.props.renderPlaceholder || this.renderPlaceholder)(); } } AsyncComponent.propTypes = { loader: React.PropTypes.func.isRequired, renderPlaceholder: React.PropTypes.func };
// BarChartAsync.js import React from 'react'; import AsyncComponent from './AsyncComponent'; const loader = (cb) => { require.ensure([], (require) => { cb(require('./BarChart')) }); } export default (props) => <AsyncComponent {...props} loader={loader}/>
// BarChartAsync.js import React from 'react'; import AsyncComponent from './AsyncComponent'; import sceduleLoad from './loader'; const loader = (cb) => { require.ensure([], (require) => { cb(require('./BarChart')) }); } sceduleLoad(loader); export default (props) => <AsyncComponent {...props} loader={loader}/>
const queue = []; const delay = 300; let isWaiting = false; function requestLoad() { if (isWaiting) { return; } if (!queue.length) { return; } const loader = queue.pop(); isWaiting = true; loader(() => { setTimeout(() => { isWaiting = false; requestLoad(); }, delay) }); } export default function sceduleLoad(loader) { queue.push(loader); requestLoad(); }
const renderPlaceholder = () => <div style={{textAlign: 'center'}}> <CircularProgress/> </div> export default (props) => <AsyncComponent {…props} loader={loader} renderPlaceholder={renderPlaceholder} />
Source: https://habr.com/ru/post/307694/