0

ここに記載されているようにAsyncCompomentクラスを実装することによって、Reactで経路を遅延ロードしようとしています。Code Splitting in Create React App以下は、チュートリアルからES6のasyncComponent機能である:遅延文字列をロードすると、文字列に一致するAsyncComponent

import React, { Component } from "react"; 

    export default function asyncComponent(importComponent) { 
     class AsyncComponent extends Component { 
     constructor(props) { 
      super(props); 

      this.state = { 
      component: null 
      }; 
     } 

     async componentDidMount() { 
      const { default: component } = await importComponent(); 

      this.setState({ 
      component: component 
      }); 
     } 

     render() { 
      const C = this.state.component; 

      return C ? <C {...this.props} /> : null; 
     } 
     } 

     return AsyncComponent; 
    } 

私はtypescriptですで、この機能を書いていると、コンポーネントが実際に遅延ロードされていることを確認することができます。私が直面する問題は、彼らがレンダリングされていないということです。私は、コンポーネントオブジェクトはcomponentDidMountフック常に不定であることを決定することができた:

//AsyncComponent.tsx 
async componentDidMount() { 
       const { default: component } = await importComponent(); 

       this.setState({ 
       component: component 
       }); 
      } 

importComponent関数から返されるオブジェクトは、次の特性をもつ。

{ 
MyComponent: class MyComponent: f, 
__esModule: true 
} 

私はcomponentDidMount方法を改変しましたこのオブジェクトの最初のプロパティ(MyComponentクラス)を取得します。この変更の後、私のプロジェクトは、コンポーネントの読み込みが遅れ、適切にレンダリングされます。

async componentDidMount() { 
      const component = await importComponent(); 

      this.setState({ 
      component: component[Object.keys(component)[0]] 
      }); 
     } 

私の最高の推測では、私はtypescriptですで正しくこの行を書いていないということです。

const { default: component } = await importComponent(); 

私はそうのようなasyncComponentメソッドを呼んでいる:

const MyComponent = asyncComponent(()=>import(./components/MyComponent)); 

誰もがどのように知っていますtypescriptでAsyncComponentを実装しますか? esModuleオブジェクトの0のインデックスを取得するだけの方法が正しいかどうかはわかりません。

答えて

1

私が必要としていたのは、遅延ロードしたいすべてのコンポーネントクラスにデフォルトをエクスポートすることでした。ここに私の完全な解決策があります:

//AsyncComponent.tsx 
import * as React from "react"; 

interface AsyncComponentState{ 
    Component: any; 
} 
export default function asyncComponent(getComponent: any): any { 
    class AsyncComponent extends React.Component<{},AsyncComponentState> { 


     constructor(props: any) { 
      super(props); 

      this.state = { 
       Component: null 
      }; 
     } 

     async componentDidMount(){ 
      const {default: Component} = await getComponent(); 
      this.setState({ 
       Component: Component 
      }); 


     } 


     render() { 
      const C = this.state.Component; 
      return C ? <C {...this.props}/> : <div>....Loading</div> 
     } 
    } 
    return AsyncComponent; 

} 
//Counter.tsx 
import * as React from 'react'; 
import { RouteComponentProps } from 'react-router'; 

interface CounterState { 
    currentCount: number; 
} 

class Counter extends React.Component<RouteComponentProps<{}>, CounterState> { 
    constructor() { 
     super(); 
     this.state = { currentCount: 0 }; 
    } 

    public render() { 
     return <div> 
      <h1>Counter</h1> 

      <p>This is a simple example of a React component.</p> 

      <p>Current count: <strong>{ this.state.currentCount }</strong></p> 

      <button onClick={() => { this.incrementCounter() } }>Increment</button> 
     </div>; 
    } 

    incrementCounter() { 
     this.setState({ 
      currentCount: this.state.currentCount + 1 
     }); 
    } 
} 
export default Counter; 

//routes.tsx 
import * as React from 'react'; 
import {Route} from 'react-router-dom'; 
import { Layout } from './components/Layout'; 
import { Home } from './components/Home'; 
import asyncComponent from './components/AsyncComponent'; 


const AsyncCounter = asyncComponent(() => import('./components/Counter')); 

export const routes = <Layout> 
    <Route exact path='/' component={ Home } /> 
    <Route path='/counter' component={ AsyncCounter } /> 
</Layout>;