ReactでDynamc Import
手持ちのReact SPAが大きく育ってきたので、そろそろスリムにしていこうと思います。 準備 コンポーネントをならべる まずはインポートさせるためのコンポーネントを並べます。 そしてComponent1 ~ 3を別ファ […]
広告ここから
広告ここまで
目次
手持ちのReact SPAが大きく育ってきたので、そろそろスリムにしていこうと思います。
準備
$ npx create-react-app react-dynamic-import
$ cd react-dynamic-import
$ yarn start
コンポーネントをならべる
まずはインポートさせるためのコンポーネントを並べます。
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const Header = () => (
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Component1 />
<Component2 />
<Component3 />
</header>
)
const Component1 = () => (
<article>
<h2>This is the <b>First</b> Component</h2>
</article>
)
const Component2 = () => (
<article>
<h2>This is the <b>Secont</b> Component</h2>
</article>
)
const Component3 = () => (
<article>
<h2>This is the <b>Third</b> Component</h2>
</article>
)
class App extends Component {
render() {
return (
<div className="App">
<Header />
</div>
);
}
}
export default App;
そしてComponent1 ~ 3を別ファイルにしていきます。コンポーネント毎にファイルを切り出すとだいたいこうなります。
$ tree src/
src/
├── App.css
├── App.js
├── App.test.js
├── Component1.jsx
├── Component2.jsx
├── Component3.jsx
├── Header.jsx
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
Dynamic Importする
それでは作ったファイルをDynamic Import化します。
import React from 'react';
import logo from './logo.svg';
import Component1 from './Component1'
import Component2 from './Component2'
import Component3 from './Component3'
class Header extends React.Component {
render() {
return (
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Component1 />
<Component2 />
<Component3 />
</header>
)
}
}
export default Header
Dynamic Importでは、コンポーネントをstateにもたせます。そのため、まずは以下のような実装にしましょう。
import React from 'react';
import logo from './logo.svg';
class Header extends React.Component {
state = {
component1: null,
component2: null,
component3: null,
}
async componentDidMount() {
// import the components
}
render() {
const { component1, component2, component3} = this.state
return (
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
{component1 || <div>...</div>}
{component2 || <div>...</div>}
{component3 || <div>...</div>}
</header>
)
}
}
export default Header
componentDidMount()
でマウントされてからコンポーネントを読むようにします。
async componentDidMount() {
const { default: Component1 } = await import('./Component1');
const { default: Component2 } = await import('./Component2');
const { default: Component3 } = await import('./Component3');
this.setState({
component1: Component1(),
component2: Component2(),
component3: Component3(),
});
}
非同期でimportしてsetStateする形です。簡単ですね。
ボタンイベントでロードしてみる
ようは何かしらの形でimportを非同期実行して、stateにいれてやればOKということですね。なのでonClickイベントを使って「ボタンをクリックした時だけロードする」ということもできます。
import React from 'react';
import logo from './logo.svg';
class Header extends React.Component {
state = {
component1: null,
component2: null,
component3: null,
}
async componentDidMount() {
const { default: Component1 } = await import('./Component1');
const { default: Component2 } = await import('./Component2');
this.setState({
component1: Component1(),
component2: Component2(),
});
}
handleClick = async (e) => {
e.preventDefault()
const { component3 } = this.state
if (!component3 || component3 === null) {
const { default: Component3 } = await import('./Component3');
this.setState({
component3: Component3(),
});
return
}
this.setState({
component3: null,
});
}
render() {
const { component1, component2, component3} = this.state
return (
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" onClick={this.handleClick} />
{component1 || <div>...</div>}
{component2 || <div>...</div>}
{component3 || <div>画像をクリックすると表示されます。</div>}
</header>
)
}
}
export default Header
こうすることでロゴ画像をクリックするたびにcomponent3を表示したり削除したりできます。
Next
Dynamic Importの威力がでるのは、おそらくReact Routerと組み合わせたときかなと思っています。表示に関係のないコンポーネントをよまなくすればロード短縮になりますので。
ということで次回はReact Routerがある状況にてトライしてみます。