Index
Working with Lists and Conditionals
Working with Lists and ConditionalsApp.js
state = {
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Amiya', age:31}
],
otherState: 'some other value',
showPersons: false
}
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Amiya', age:31}
],
otherState: 'some other value',
showPersons: false
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons:!doesShow})
}
const doesShow = this.state.showPersons;
this.setState({showPersons:!doesShow})
}
onClick={this.togglePersonsHandler}
{
this.state.showPersons === true ?
<div>
</div> : null
}
<button style={style} onClick={this.togglePersonsHandler}>Toggle Persons</button>
{
this.state.showPersons === true ?
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div> : null
}
{
this.state.showPersons === true ?
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div> : null
}
Linked file: toggle.gif |
App.js
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Amiya', age:31}
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
this.setState({
persons: [
{ name: newName, age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Omy', age:12}
]
})
}
nameChangedHandler = (event) => {
this.setState({
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: event.target.value, age:26},
{ name: 'Amiya', age:31}
]
})
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons:!doesShow})
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
return (
<div className="App">
<h1>Hi, I'm a React App!!!</h1>
<button style={style} onClick={this.togglePersonsHandler}>Toggle Persons</button>
{
this.state.showPersons === true ?
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div> : null
}
</div>
);
}
}
export default App;
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Amiya', age:31}
],
otherState: 'some other value',
showPersons: false
}
switchNameHandler = (newName) => {
this.setState({
persons: [
{ name: newName, age: 28},
{ name: 'Manu', age: 29},
{ name: 'Stephanie', age:26},
{ name: 'Omy', age:12}
]
})
}
nameChangedHandler = (event) => {
this.setState({
persons: [
{ name: 'Max', age: 28},
{ name: 'Manu', age: 29},
{ name: event.target.value, age:26},
{ name: 'Amiya', age:31}
]
})
}
togglePersonsHandler = () => {
const doesShow = this.state.showPersons;
this.setState({showPersons:!doesShow})
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
return (
<div className="App">
<h1>Hi, I'm a React App!!!</h1>
<button style={style} onClick={this.togglePersonsHandler}>Toggle Persons</button>
{
this.state.showPersons === true ?
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div> : null
}
</div>
);
}
}
export default App;
Handling Dynamic Content The JavaScript Way
Refactoring the code:
let persons = null;
if(this.state.showPersons){
//html
}
render() {
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App!!!</h1>
<button style={style} onClick={this.togglePersonsHandler}>Toggle Persons</button>
{persons}
</div>
);
}
}
const style = {
backgroundColor: 'white',
font: 'inherit',
border: '1px solid blue',
padding: '8px',
cursor:'pointer'
};
let persons = null;
if(this.state.showPersons){
persons = (
<div>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}/>
<Person name={this.state.persons[2].name}
age={this.state.persons[2].age}
click={this.switchNameHandler.bind(this,'NewMax!!!')}
changed={this.nameChangedHandler}
>My Hobbies: Racing</Person>
<Person name={this.state.persons[3].name} age={this.state.persons[3].age} />
</div>
);
}
return (
<div className="App">
<h1>Hi, I'm a React App!!!</h1>
<button style={style} onClick={this.togglePersonsHandler}>Toggle Persons</button>
{persons}
</div>
);
}
}
Outputting Lists (Intro)
Mapping each item and return jsx:
{this.state.persons.map(person => {
return <Person
name={person.name}
age = {person.age}
/>
})}
return <Person
name={person.name}
age = {person.age}
/>
})}
Lists State
Delete Indexes
deletePersonHandler = (personIndex) => {
const persons = this.state.persons;
persons.splice(personIndex,1);
this.setState({persons:persons});
}
const persons = this.state.persons;
persons.splice(personIndex,1);
this.setState({persons:persons});
}
You can have another argument that gets the index:
{this.state.persons.map((person,index) => {
return <Person
click= {() => this.deletePersonHandler(index)}
name={person.name}
age = {person.age}
/>
})}
Linked file: splice.gif |
Updating State Immutably
Good practice is to create a copy of the persons array without using the reference
You can use slice method:
const persons = this.state.persons.slice();
Alternative is use spread feature of ES6:
const persons = [...this.state.persons];
deletePersonHandler = (personIndex) => {
const persons = [...this.state.persons];
persons.splice(personIndex,1);
this.setState({persons:persons});
}
Removing the error:
state = {
persons: [
{ id: 'abc1', name: 'Max', age: 28},
{ id: 'abc2', name: 'Manu', age: 29},
{ id: 'abc3', name: 'Stephanie', age:26},
{ id: 'abc4', name: 'Amiya', age:31}
],
otherState: 'some other value',
showPersons: false
}
{this.state.persons.map((person,index) => {
return <Person
click= {() => this.deletePersonHandler(index)}
name={person.name}
age = {person.age}
key = {person.id}/>
})}
key property is default property that react expect to find, when you do mapping an array,
key property helps the react to update the list efficiently
key property should get something unique, e.g. id of database.
Flexible Lists:
{this.state.persons.map((person,index) => {
return <Person
click= {() => this.deletePersonHandler(index)}
name={person.name}
age = {person.age}
key = {person.id}
changed={(event) => this.nameChangedHandler(event, person.id)}/>
}
return <Person
click= {() => this.deletePersonHandler(index)}
name={person.name}
age = {person.age}
key = {person.id}
changed={(event) => this.nameChangedHandler(event, person.id)}/>
}
nameChangedHandler = (event, id) => {
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;
});
const person = { ...this.state.persons[personIndex]
};
person.name = event.target.value;
const persons = [...this.state.persons];
persons[personIndex] = person;
this.setState({
persons: persons
});
}
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;
});
const person = { ...this.state.persons[personIndex]
};
person.name = event.target.value;
const persons = [...this.state.persons];
persons[personIndex] = person;
this.setState({
persons: persons
});
}
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;
});
Just like map, it takes every element of persons array, and returns true, if id matches with the person id.
const person = { ...this.state.persons[personIndex]
};
Its a good practice to not mutate the state of persons directly, so we use spread operator to create a copy the person of the persons.
person.name = event.target.value;
It will change the person name to that you have changed in the form in UI
const persons = [...this.state.persons];
copy the persons array
persons[personIndex] = person;
Then mutate the copied persons array to assigning a new value to the person with the index.
this.setState({
persons: persons
});
Now update the state, with using the copied persons array.
Lot of code, but best way of doing it without mutating the state.
You also no longer get these warning.
Linked file: edit.gif |