Meteor 1.5 how to dynamically import React components

Hi guys I’m trying to dynamically import a React component. Can you please help me?
Here is my code.

import React, { Component } from 'react'

export default class PopupDesigner extends Component {
state = {
      dynamicComponentStatus: {
        isLoaded: false,
        MyComponent: null
      }
    }

  componentDidMount () {
    console.warn('componentDidMount')
    import('../Templates/Template1').then((MyComponent) => {
      console.warn('import!')
      this.setState({
          isLoaded: true,
          MyComponent: MyComponent
        })})
  }
  render () {

            console.log('this.state.dynamicComponentStatus.isLoaded', this.state.dynamicComponentStatus.isLoaded)
            console.log('this.state.dynamicComponentStatus.MyComponent', this.state.dynamicComponentStatus.MyComponent)
            return this.state.dynamicComponentStatus.isLoaded && this.state.dynamicComponentStatus.MyComponent

  }
}

Can you please tell me what am I missing here?

Your initial state is

{
    dynamicComponentStatus: {
        isLoaded: false,
        MyComponent: null
    }
}

whereas you are updating:

{
    isLoaded: true,
    MyComponent: MyComponent
}

And then later on you’re querying for this.state.dynamicComponentStatus.isLoaded and this.state.dynamicComponentStatus.MyComponent which, you have never updated!

1 Like

This is how ViewModel more or less does it underneath the hood:

import React from "react";
export class App extends React.Component {
  render() {
    return <div>
      {
        this.BigComponent || import("./BigComponent/BigComponent").then(m => {
          const BigComponent = m.BigComponent;
          this.BigComponent = <BigComponent />;
          this.setState({});
        }) && null
      }
    </div>;
  }
}

This is how it works “above the hood”:

App({
  render() {
    <div>
      <BigComponent b="defer: true" />
    </div>
  }
})
3 Likes

You could use react-loadable https://github.com/thejameskyle/react-loadable

To answer your question - you are returning the component constructor, and not an instance, change the last line in your render method:

const {isLoaded, MyComponent} = this.state.dynamicComponentStatus
return isLoaded && <MyComponent />

Note the brackets :wink: This is in addition to what @serkandurusoy said above about the structure of your state object

3 Likes