Skip to content
Advertisement

React updating only first element of list on triggering onChange

I am trying to build a flexible list with an input field so that whenever I write something in that input field it changes the value.

Like this: enter image description here

But, in whichever input field I type it changes the only name of first field alone.

Like there are 3 input field and 3 paragraph tag according to state. I want to update the input field’s above p tag (displaying the name) onChange of input field.

I am trying to implement this function using React hooks.

Here is my code:

App.js

const initialPersonState = [
    {name:"Vivank",age:"21"},
    {name:"Shubham",age:"18"},
    {name:"Max",age:"16"},
  ]

  const [personState, setPersonState] = useState(initialPersonState)
const inputChangeHandeler = (event,id) => {
    const personIndex = personState.findIndex(p =>{
      return p.id === id
    })

    const person = {
      ...personState[personIndex]
    }

    person.name = event.target.value

    const persons = [...personState]
    persons[personIndex] = person

    setPersonState(persons)
  }

person = (
      <>
        {personState.map((person,index)=>{
          return <Person 
          name={person.name}
          age={person.age}
          delete={() => deletePerson(index)}
          key={person.id}
          change={(event)=>inputChangeHandeler(event,person.id)}
          />
        })

        }
      </>

Person.js

const person = (props) => {
    return(
        <div>
            <p onClick={()=>props.click("Max!")}>Hello my name is {props.name} and I'm {props.age} years old</p>
            <p>{props.children}</p>
            <p onClick={props.delete}>Delete person</p>
            <input type="text" onChange={props.change}></input>
        </div>
    );
}

Advertisement

Answer

You need to pass the value of name to the input. So your person component should look like this:

const person = (props) => {
    return(
        <div>
            <p onClick={()=>props.click("Max!")}>Hello my name is {props.name} and I'm {props.age} years old</p>
            <p>{props.children}</p>
            <p onClick={props.delete}>Delete person</p>
            <input type="text" value={props.name} onChange={props.change}></input>
        </div>
    );
}

Also, you haven’t defined id inside person info objects, initial state should look like

const initialPersonState = [
    {id: 1, name:"Vivank",age:"21"},
    {id: 2, name:"Shubham",age:"18"},
    {id: 3, name:"Max",age:"16"},
  ];
Advertisement