简体   繁体   中英

Rendering Multiple React Components with .map

This may be a complete noob question, but I am having trouble figuring this out. I have a React component, and inside its render method, I want to render some dynamically passed in components (through props).

Here's my return from the render method (ES6, transpiled with Babel)

return (
    <div className={openState}>
    /* Shortened for brevity*/
    {this.props.facets.map(function(f) {
        var CompName = facetMap[f.type]
        return <CompName key={f.id} />
    })}
    /* Shortened for brevity*/
    </div>
)

facetMap is simply a map to match up a string to the "type" passed in. I can't seem to get the components to actually render on the page.

I had the result of the .map() method stored in a var, and then logged that to the console, and it showed an array of components. However {facetComponents} in the render method had the same results.

EDIT, for those interested in the solution

Because I genuinely could not find an answer anywhere, here's my completed solution, thanks to @Mathletics

//Components imported using ES6 modules
import OCFacetText from "./oc-facet-text"
// Etc... 

//Later on, in my render method:
let facetMap = {
    "text":         OCFacetText,
    "number":       OCFacetNumber,
    "numberrange":  OCFacetNumberRange,
    "boolean":      OCFacetBoolean,
    "checkbox":     OCFacetCheckbox,
    // Etc, etc... 
}

let facetComps = facets.map(function(f) {
    var CompName = facetMap[f.type]
    return <CompName key={f.id} />
})

//Finally, to render the components:
return (
    <div className={openState}>
    /* Shortened for brevity*/
        {facetComps}
    /* Shortened for brevity*/
    </div>
)

Annoying one.

If you want dynamic component names you'll have to utilize React.createElement(CompName) , where CompName is a string or the class object.

By default react will look for a component named CompName in your above example.

So your render function would look like so:

return (
    <div className={openState}>
    /* Shortened for brevity*/
    {this.props.facets.map(function(f) {
        var CompName = facetMap[f.type]
        return React.createElement(CompName, {key: f.id}) />
    })}
    /* Shortened for brevity*/
    </div>
)

From what I can gather, it sounds like your facetMap is a collection of strings:

var facetMap = {text: 'OCFacetText'}

but it should actually return component classes:

var OCFacetText = React.createClass({...});

var facetMap = {text: OCFacetText};

Then (and only then) you will need to use the createElement method to construct your component dynamically:

var CompName = facetMap[f.type]; // must be a FUNCTION not a string
return React.createElement(CompName, {key: f.id}) />

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