Now we added a lot of functionality and learned about the key, let’s find out you in our application bit more because in persons component we still have that input where we have to onChange handler where we try toexecute changed prop and also get a value as an input.
persons
input
onChange
import React from 'react'; import './Person.css'; const person = props => { return ( <div className="Person"> <p onClick={props.click}> {/* on click will execute the deletePersonHandler method */} I am a {props.name} and i am {props.age} year old! </p> <p> {props.children} </p> <input type="text" onChange={props.changed} value={props.name} /> </div> ); }; export default person;
Now that we render a list and have truly dynamic content we can finally set this up in a truly dynamic way. So what we need to do is we simply need to provide these changes pointing to some event listener or to some method which correctly updates the state.
So in App.js we will add changed and that will point to the method, we got the nameChangeHandler method, so let’s simply use that method. in name nameChangeHandler we will need to arguments i.e. event value to change name and ID of the user to be updated
nameChangeHandler
event
ID
... nameChangeHandler = (event, id) => { // will now accepts two parameters // ... } ...
And in render() methos will also pass the arguments
render()
... return ( <Person click={() => this.deletePersonHandler(index)} name={person.name} age={person.age} key={person.id} changed={event => this.nameChangedHandler(event, person.id)} /> ); ...
And with that we can now use that information in the nameChangeHandler. We want to update the state but of course only for the person into which input field we typed.
So we need to find that person, We can do this by reaching out to that this.state.persons calling .findIndex() method to find element in array but then get the index of the element.
this.state.persons
.findIndex()
... nameChangeHandler = (event, id) => { const personIndex = this.state.persons.findIndex( p => p.id === id) // will return Index of the matched ID ... } ...
Then will access to that element by using that matched ID that we got by using findIndex() method.
findIndex()
... nameChangeHandler = (event, id) => { const personIndex = this.state.persons.findIndex( p => p.id === id); const person = { ...this.state.persons[personIndex] }; // Morden approach to copy the object } ...
Then ofcourse we want to update the persons name and we can do that because we got a copy, I am not manipulating the original object I can set it to event.target.value
event.target.value
... nameChangeHandler = (event, id) => { const personIndex = this.state.persons.findIndex( p => p.id === id); const person = { ...this.state.persons[personIndex] }; person.name = event.target.value; // Set event value to bind name } ...
Now i need to update the array, so just as before I can now get my persons the whole array we have to spread operator. as we always be working with copies.
... nameChangeHandler = (event, id) => { const personIndex = this.state.persons.findIndex( p => 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}) } ...
We got an updated array and we have setState method which will update the old array. you might feel a lot of code but its a best way of doing it the most efficient way without mutating the state.
Now save and run the code you will not find any error on console and on the update of the input field, it updates name what you have entered.