8

I'm building a web app using React that shows the blueprint for the building you select, in an already selected campus.

I have a "Content" component that loads the campus or building map, depending what you chose. The "BuildingMap" component needs to load a specific blueprint according to what building you selected. It gets the props.building with the name of the building but I don't know how to load a component using that variable.

I have tried import, fetch and require but nothing seems to work.

Please help.

My code looks something like this:

//Content Component

<BuildingMap building={selectedBuilding} campus={selectedCampus} />

//BuildingMap Component

import *MyBlueprint* from (specific folder depending on the campus selected)

class BuildingMap extends React.Component {
  render(){
    return (
      <div className="blueprint" id={this.props.building}>
         {*MyBlueprint*}
      </div>
    )
  }
}
1
  • Is it a requirement that you load the module at runtime as opposed to packing the components into an object and referencing them by key? The latter is far more common. Commented May 31, 2017 at 21:45

3 Answers 3

4

Unfortunately, you cannot import/require components dynamically in React environment.

Depending on how many buildings/blueprints there are, it's possible to import them one by one, create component-building map and pick component by building ID.

If there are many/infinite components to load, I would surely pick another method - don't know content of your problem.

import BlueprintA from './BlueprintA'
import BlueprintB from './BlueprintB'
import BlueprintC from './BlueprintC'
// ...

class BuildingMap extends React.Component {
  render(){
    const C = {
      buildingA: BlueprintA,
      buildingB: BlueprintB,
      buildingC: BlueprintC,
      // ...
    }[this.props.building]

    return (
      <div className="blueprint" id={this.props.building}>
         <C />
      </div>
    )
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

It is possible to load modules dynamically, but certainly more rare for this type of circumstance, your solution is fine 99% of the time. I would also put the object construct outside of the component in case it could be used elsewhere. a good option for that could be import * as blueprints from ..
Well, what I meant was it's not possible to import/require module dynamically - by value of variable, e.g. Importing all named modules is option here. Thanks for mentioning :)
It is possible to require module dynamically, though with a variable name. example: github.com/NCI-GDC/portal-ui/blob/relay/src/packages/%40ncigdc/…
Sorry for the noob question but what does this mean? const C = { buildingA: BlueprintA, // ... }[this.props.building] I don't understand the last bit, what does the [this.props.building] mean?
3

This question is pretty old but as I was looking for how to solve the same problem let me give my answer. It can be done with dynamic import React.lazy:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

See more details here: https://reactjs.org/docs/code-splitting.html#reactlazy

Comments

2

To add to @Andreyco's answer:

Using a lookup table of string IDs/names to component classes is a typical React idiom. One common use case is a modal manager component that can render multiple different types of modals. For some examples, see Dan Abramov's answer at "How can I render a modal dialog in Redux?" (not Redux-specific), as well as some of the related articles in the React Component Patterns#Modal Dialogs and Redux Techniques#UI sections of my React/Redux links list.

Per @azium's comment: it is definitely possible to use dynamic importing (via require.ensure() or the new import() function) to load chunks at runtime, and you could add the exports from those dynamically imported chunks into a lookup table when they are loaded.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.