1

I'm kinda new to React and i try to figure out how to change the state of my object's. But when i change the state in my input field the field is rerenderd at the bottom.

How can i keep my input field on the same place as it's renders the first time.

class App extends Component {
    state = {
        persons: [{
            id: 0,
            name: ''
        },{
            id: 1,
            name: ''
        }]
    }
    
    changePersonNameHandler = event => {
        const id = parseInt(event.target.id);
        const newPersonName = event.target.value;

        this.setState({
            persons: [...this.state.persons.filter(i => i.id !== id),
                {
                    id,
                        name: newPersonName,
                }
            ]
        })
    }
    
    render () {
        const {persons} = this.state;
        
        return (
          <div>
            <ul>
              {persons.map((i, index)  => (
                  <li key={i.id}>
                      <label>Name: </label>
                      <input id={i.id}
                           value={i.name}
                           onChange{this.changePersonNameHandler}/>
                  </li>
                  )
              )}
            </ul>
          </div>
        )
    }
}

2 Answers 2

2

filter removes an item and you lose its position. To modify an item and keep its place in the array use map. Also it is better not rely on this.state to get a new value for setState. You should use setState(oldState => newState) instead.

changePersonNameHandler = event => {
    const id = parseInt(event.target.id);
    const newPersonName = event.target.value;

    this.setState(old => {
        const persons = old.persons.map(
            person => person.id !== id ? person : {id, name: newPersonName}
        );
        return {persons};
    })
}
Sign up to request clarification or add additional context in comments.

Comments

1

Each time you're doing a change, you put the edited person at the end of the array in your handleChange method.

Just invert the edited one and the existing ones in setState and it will do the trick.

this.setState({
  persons: [{
      id,
      name: newPersonName,
    }, 
    ...this.state.persons.filter(i => i.id !== id)
    ]
  })
}
  • There is a missing = sign after onChange in the code you gave but I guess in your local code it's ok.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.