react-router(v4)でDynamic Import

前回の続きです。 やりたいこと そのページでしか使わないコンポーネントは、Dynamic Importにしたい 想定 以下のようなURL構造のページを想定します。 / :トップページ /page1 : ページ1 /pag […]

広告ここから
広告ここまで

目次

    前回の続きです。

    やりたいこと

    そのページでしか使わないコンポーネントは、Dynamic Importにしたい

    想定

    以下のようなURL構造のページを想定します。

    • / :トップページ
    • /page1 : ページ1
    • /page1/hello :ページ1の子ページ
    • /page2 : ページ2
    • /page2/hello :ページ2の子ページ

    実装

    結論から書くと、このような形でできます。

    
    import React, { Component } from 'react';
    import { Route, Switch, Link } from 'react-router-dom';
    const LinkStyle = {color: '#fff', margin: '5px'}
    
    class Page2 extends Component {
      state = {
        Page2Home: null,
        Page2Child: null,
      }
      async componentDidMount() {
        const { default: Page2Home } = await import('./Page2Home');
        const { default: Page2Child } = await import('./Page2Child');
        this.setState({
          Page2Home,
          Page2Child,
        });
      }
      render () {
        return (
          <>
            <h1>Page2</h1>
            <div style={{display: 'flex', zIndex: 2}}>
              <Link style={LinkStyle} to="/page2">home</Link>
              <Link style={LinkStyle} to="/page2/hello">child</Link>
            </div>
            <Switch>
              <Route component={this.state.Page2Child} path="/page2/hello" />
              <Route component={this.state.Page2Home} path="/" extract />
            </Switch>
          </>
        )
      }
    }
    
    export default Page2

    setStateする際、classなら変数をそのまま入れます。SFCならComponent()のように実行してやりましょう。

    ネストも可能

    親でさらにDynamic Importすることも可能な様子です。

    import React, { Component } from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import './App.css';
    import Header from './Header';
    
    class App extends Component {
      state = {
        Page1: null,
        Page2: null,
      }
      async componentDidMount() {
        const { default: Page1 } = await import('./Page1');
        const { default: Page2 } = await import('./Page2');
        this.setState({
          Page1,
          Page2,
        });
      }
      render() {
        return (
          <div className="App">
            <Router>
              <div className="App-header">
                <Header />
                <Switch>
                  <Route component={this.state.Page2} path="/page2" />
                  <Route component={this.state.Page1} path="/page1" />
                  <Route component={() => <div><h1>Home</h1></div>} path="/" extract />
                </Switch>
              </div>
            </Router>
          </div>
        );
      }
    }
    
    export default App;

    これを追加しても、孫ページのロードは問題ありませんでした。

    注意点

    あくまでreact-router(v4)とつないでテストしたのみの結果です。実際にはここに非同期処理が入りますので、いろいろと勝手が異なる可能性が大いに出てくることはご留意ください。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark