Search code examples
loopsswitch-statementreactjs

Using for loops and switch cases in React to dynamically render different components


I am trying to render components conditionally using switch case in React JSX. I am trying to build something that reads from a specific json structure and renders the data. Since there can be many different components and data, I am trying to render it dynamically. See my code below, I am not getting any errors but the components aren't getting rendered. Inside my html , I can only see . This means the loop isn't working. I tried using the same loop in vanilla JS and it works.

var myPackage = [{
    sectionInfo:[{
        elementType: 1,
        text: "This is text from element type 1"
    }]
},
{
    sectionInfo:[{
        elementType: 2,
        text: "This is text from element type 2"
    }]
}];
var App = React.createClass({

    render: function(){
        var elements = [];
        elements = myPackage.map(function(myObj){
            myObj.sectionInfo.map(function(myObj1){
                switch(myObj1.elementType){
                    case 1: return(
                                <Component1 text = {myObj1.text}/>
                            );
                            break;
                    case 2: return(
                                <Component2 text = {myObj1.text}/>
                            )
                            break;      
                }
            })
        });
        return(
            <div className="App">
                {elements}
            </div>
        )
    }
});
var Component1 = React.createClass({
    render:function(){
        return(
            <div className = "element1">
                {this.props.text}
            </div>
        )
    }
});
var Component2 = React.createClass({
    render:function(){
        return(
            <div className = "element2">
                {this.props.text}
            </div>
        )
    }
});
ReactDOM.render(<App/>,document.getElementById('container'));

Edit: Made a few additions to the code, and now I am facing a new problem. Here is the new code:

var App = React.createClass({

        render: function(){
            var elements = [];
            elements = myPackage.map(function(myObj){
                return(
                       <div>
                           myObj.sectionInfo.map(function(myObj1){
                           switch(myObj1.elementType){
                           case 1: return(
                                    <Component1 text = {myObj1.text}/>
                                );
                                break;
                           case 2: return(
                                    <Component2 text = {myObj1.text}/>
                                )
                                break;      
                        }
                        }
                  </div>
                )
                });
        return(
            <div className="App">
                {elements}
            </div>
        )
    }
});

I want to render each time inside a div. So that if one section has more than 3 elements, then all 3 must be inside a div.


Solution

  • You should return value from first .map, in your case it is result from inner .map

    var elements = myPackage.map(function(myObj){
      return myObj.sectionInfo.map(function(myObj1) {
         // ...  
      });
    });
    

    Update:

    Based on your new update, you can change your code like this

    var App = React.createClass({
    
      section: function(myObj, parentIndex) {
        return myObj.sectionInfo.map(function(myObj1, index) {
          const key = parentIndex + '.' + index;
    
          switch(myObj1.elementType) {
            case 1:
              return <Component1 text = {myObj1.text} key={ key } />
            case 2:
              return <Component2 text = {myObj1.text} key={ key } />
          }
        });
      },
    
      render: function() {
        var elements = myPackage.map(function(myObj) {
          return <div>
            { this.section(myObj, index) }
          </div>
        }, this);
    
        return <div className="App">
         { elements }
        </div>;
      }
    });