sdpercussion sdpercussion - 1 month ago 10
React JSX Question

How to get my handleClick to render different components

I am a beginner so please excuse my ignorance. I am posting one component from a larger app that I am building. This component has a handleClick function that changes the state when an image is clicked. When the image is clicked, a new component is rendered. Currently, the same 'new component' is rendered no matter which image is clicked. I'd like the component to be based on which image was clicked.

var AllocationDiv = React.createClass({
getInitialState: function(){
return {clicked: false};
},
handleClick: function() {
this.setState (
{clicked: true}
);
},
render: function () {
var handleFunc = this.handleClick; //because it wasn't brining this.handleClick into the render function
var chartMap = pieCharts.map(function(prop){
return <img onClick={handleFunc} id={prop} src={prop} />;
});
return (
<div id='bottomSection'>
<h2>Select Desired Asset Allocation</h2>
<div id='pieCharts'>
<table>
<tr>{pieHeadMap}</tr>
</table>
<div>
{chartMap}
<div id='test'>
{this.state.clicked ? <TestComponent /> : null}
</div>
</div>
</div>
</div>
);
}
});


var chartMap renders three images. Assuming I create three unique test components, how would I get them to be rendered depending on which image was clicked? Here is the entire app. I know the whole thing is a mess atm, but I'm using this as a sandbox to learn through problem-solving. Thanks!
http://codepen.io/sdpercussion/pen/NRQNLv?editors=0010

Answer

So, here is what I would do for this. Instead of having a boolean value for your clicked state, you should have a string. The string should be the name of the image being clicked. (you need to assign names or ID's or anything to differentiate them)

so.. initial state is:

getInitialState: function(){
  return {clicked:''};
},

next your handleClick would have to change and you'd need to pass the image name/Id in to it.

handleClick: function(image) {
  this.setState ({
    clicked: image
  }); 
},

then, inside your render..

(make sure to .bind(this) in your map so you can use the component scope if you want to call your methods. var self = this; type workarounds show a misunderstanding of scope)

render: function () {

    var chartMap = pieCharts.map(function(prop){
      // pass in your image name to your callback using bind, null value here skips over the scope portion and is what you need
      return <img onClick={this.handleClick.bind(null, prop)} id={prop} src={prop} />;
    }.bind(this)); 

    // get the component you want for each specific image and save to a variable for display
    var imgVar = null;
    switch (this.state.image) {
        case 'image1':
            imgVar = <NewComponent />;
            break;
        case 'image2':
            imgVar = <DifferentComponent />;
            break;
    }

    return (
      <div id='bottomSection'>
          <h2>Select Desired Asset Allocation</h2>
          <div id='pieCharts'>
            <table>
              <tr>{pieHeadMap}</tr>
            </table>
              <div>
                {chartMap}
                  <div id='test'>  
                    {imgVar}
                  </div>
              </div>
            </div>
        </div>
    );
  }
Comments