So we are back in App.js file in there the render() method which we learned is used when creating a component by extending Component class, and there we already have outout the three Person component and that clearly is kind of a list because we also have person managed in our state = {...} object. It would make sense to output this as a list but before we dive into that, let’s dive into outputting content conditionally. first, let’s say when we click the button we don’t want to switch the names as we have done in the previous lesson. But let’s say instead we want to show or hide the person components which we have in App.js
render()
Component
Person
state = {...}
For now we can simply wrap all the Person components in div so at the end we can show or hide and automatically also show everything thats inside the div thats the idea behind wrapping all the Person component. The first step
div
... return ( <button style={style} onClick={() => {this.switchNameHandler('somename')}}> Switch Name </button> <div> <Person name={this.state.persons[0].name} age={this.state.persons[0].age} /> <Person click={this.switchNameHandler} name={this.state.persons[1].name} age={this.state.persons[1].age} changed={this.nameChangedHandler} /> <Person name={this.state.persons[2].name} age={this.state.persons[2].age} /> </div> ); ...
The second step we will change the method of onClick applied on a button and will name it to togglePersonsHandler() and no longer will pass an argument to that method.
onClick
togglePersonsHandler()
... return ( {/* <button style={style} onClick={() => {this.switchNameHandler('somename')}}> Switch Name </button> */} <button style={style} onClick={this.togglePersonsHandler}> Switch Name </button> ); ...
Now also we have to create a togglePersonsHandler method in App.js. So will will add a new method with a name togglePersonsHandler method above the render() method.
togglePersonsHandler
... class App extends Component { togglePersonsHandler = () => { } render(){ ... } } ...
Now in there to target some property which in the end the sites wherever we want to display the newly added div with the persons inside of it or not. For that I will go into the state and add a new property names as showPersons the name is ofcourse is up to you, and will set that value to false initially.
showPersons
class App extends Component { state = { persons: [{ name: 'Lucy', age: 23 }, { name: 'Max', age: 12 }, { name: 'Mike', age: 34 }], showPersons: false, }; ... }
now if the state showPersons is false then i dont want to show the persons and how can we now render this dynamically. well we can go that div, In other frameworks like Angular or Vuejs you would now place a directive on that div for example angular we use the ng-if='expression'. but in react it works different. Always keep in mind we are working with javascript only it might look like HTML what we render but at the end it is JSX it is just syntactical sugar forreact create element. Now to show the content dynamically we can enclose the div in like { <div> ... </div> } between the single curly barces you can write javascript expressions thats not only true for 2+2 or for reaching out for the state, but also you can render content conditionally by adding a ternary expression. What you cant do in that is an if statement ( if(/* Condition */){ } ) and moving the div block inside if statement but that dosent work here. You can actually use simple statement no block statements as parts of that dynamic syntax. We can simply check like if this.state.showPersons keep in mind this is a boolean we assign false initially. So the statement will give us true or false and now ternary expressin which is a default javascript construct checks this condition by adding a ? and then we decide what to do if this is true and else part will be after `:` For Example :
ng-if='expression'
{ <div> ... </div> }
2+2
if(/* Condition */){ }
this.state.showPersons
class App extends Component { ... render() { const style = { ... }; return ( <div className="App"> <h1> Heading</h1> <button style={style} onClick={this.togglePersonsHandler}> Switch Name </button> {this.state.showPersons ? ( <div> <Person name={this.state.persons[0].name} age={this.state.persons[0].age} /> <Person click={this.switchNameHandler} name={this.state.persons[1].name} age={this.state.persons[1].age} changed={this.nameChangedHandler} /> <Person name={this.state.persons[2].name} age={this.state.persons[2].age} /> </div> ) : null} {/* else render nothing */} </div> ); } ... }
this might be looking super confusing the first time you use it, I am aware of this. So what we in the end do here is we simply take advantage of the fact that all we write here is in javascript and we can inteject javascript expressions into JSX with single curly braces. Now with this lets complete our logic but making sure that the togglePersonsHandler correctly switches to state.
class App extends Component { ... togglePersonsHandler = () => { const doesShow = this.state.showPersons; // this either can be true or false this.setState({showPersons: !doesShow}); } render(){ ... } ... }
this.setState({showPersons: !doesShoe}) will togglw the showPersons value i.e. if it is true it will set false and if its true then it will set to false. after saving all the code and make sure npm start is running. you will find that no persons component is visible … once you click the button the persons component is been rendered on the page. This is how conditional statement works in react. We already got a working conditional check now writing conditionals like this though does work but can also lead to confusing JSX code If you have a lot of possibly even nested checks so I will show you an alternative to this in the next lesson.
this.setState({showPersons: !doesShoe})
npm start