简体   繁体   中英

How to load Component dynamically in reactjs?

I'm working on a Reactjs + React-motion project, in a "modal window" (let's say) I'd like to mount or load a component dynamically, if that's possible ?

My solution so far: I couldn't find a way, so it seems that it's easier to have the component in place, and hide it, then toggle a class or style on state change, revealing the hidden component and only after the "modal window" transition finishes.

Sharing some code below where it's easier to understand what I'm trying to do. There's no event handlers and most code was removed, but the onRest (the event callback when the animation finishes is exposed) and also the render fn.

class HomeBlock extends React.Component {

    constructor (props) {
        ...

    }

    ...

    motionStyleFromTo () {

        return {
            ...
        };

    }

    onRest () {

        // this is triggered when the Motion finishes the transition

    }

    render () {

        return (
            <Motion onRest={this.onRestCallback.bind(this)} style={this.motionStyleFromTo()}>
                {style =>
                    <div className="content" style={{
                        width: `${style.width}px`,
                        height: `${style.height}px`,
                        top: `${style.top}px`,
                        left: `${style.left}px`
                        }}>
                        [LOAD COMPONENT HERE]
                    </div>
                }
            </Motion>
        );

    }

}

export default HomeBlock;

You can achieve this quite easily. In this example I am rendering a component dynamically based on a prop:

class MyComponent extends React.Component {
  propTypes: {
    display: React.PropTypes.bool
  },
  render() {
    return (
       <div>
         {this.props.display ? <ChildComponent /> : null}
       </div>
    )
  }
}

In your case you may want to use internal component state to mount or unmount the component.

FYI there are cases where you might prefer or need to use style to hide components instead of destroying them. There is more about this in the React documenation. See the 'Stateful Children' section here: https://facebook.github.io/react/docs/multiple-components.html

You can do it using dependency injection and dependency container concept. I have provided some sample code at this gist page

https://gist.github.com/SamanShafigh/a0fbc2483e75dc4d6f82ca534a6174d4

So let assume you have 4 components called D1, D2, D3. What you need is to create a dependency injection and a dependency container mechanism. This is a very simple implementation

Imagine you have a config file like this that defines your components

export default [
  {
    name:'D1',
    path:'D1'
  },
  {
    name:'D2',
    path:'D2'
  },
  {
    name:'D3',
    path:'D3'
}];

Then you can have a component container something like this

import componentsConfig from 'ComponentsConfig';

let components = {};

for (var i = 0; i < componentsConfig.length; i++) {
  let componentConfig = componentsConfig[i];
  // Check if component is not already loaded then load it
  if (components[componentConfig.name] === undefined) {
    components[componentConfig.name] = require(`${componentConfig.path}`).default;
  }
}

export default components;

Finally in the place you want to load your components you can use your component container to load your components dynamically or in other word you can inject your components

import React, { Component } from 'react';
import ComponentContainer from './ComponentContainer';

class App extends Component {
  render() {
    let components = ['D1', 'D2', 'D3'];

    return (
      <div>
        <h2>Dynamic Components Loading</h2>
        {components.map((componentId) => {
          let Component = ComponentContainer[componentId];
          return <Component>{componentId}</Component>;
        })}
      </div>
    );
  }
}

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM