0

why is this so difficult to do or find an answer for?

I have my state

state: {
   people: [
     {name: 'tom'},
     {name: 'rich'},
   ]
}

why is it so hard to update the name Tom to Pete for example?

const people = this.state.people.slice();
people[i].name = value;
this.setState({ people });

I can do this but 1) i is undefined and 2) it just seems messy

is there not a more elegant solution to update object keys??

The Walrus
  • 1,148
  • 6
  • 28
  • 46

3 Answers3

0

If you try to rename first element you need to pass integer index:

const people = this.state.people.slice();
people[0].name = value;
this.setState({ people });

If you need rename element specify by name tom, use for example es6 .findIndex method:

const people = this.state.people.slice();
const index = people.findIndex(item => item.name === 'tom');
if(index >= 0) {
  people[index].name = value;
}
this.setState({ people });
Artem Mirchenko
  • 2,140
  • 1
  • 9
  • 21
0

you aren't looping though anything so yes i is undefined.

lets say you have a click handler for an item..

{this.state.people.map( (person, idx) => <div onClick={this.handleClick.bind(this, idx)>Person here!</div>)}

now from here you have an index to update the record from...

then your person to update you can get in the handle function const person = {...this.state.people[idx]}

notice i make a new object here for the person so were sure to not mutate a state object directly. assuming you have another value or state variable somewhere you can then assign that value to that person

EDIT:

handleClick = (idx, e) => {
    const { value } = e.target;
    const robots = [].concat(this.state.robots);
    const robot = robots[idx]
    robot.name = value;
    robots[idx] = robot;
    this.setState({robots})
}
John Ruddell
  • 25,283
  • 6
  • 57
  • 86
  • im very confused. your way works but I still get error saying it `cant read e of undefined` `updateRobotName = (index) => { const { value, name } = e.target; //the e here const newRobot = {...this.state.robots[index]} }` but when I remove this line, it then doesn't work?? and when I pass `e` into the function, it still doesn't work?? – The Walrus Apr 09 '18 at 07:28
  • I would love to help but I need to see code or more of what is going on to give a good / correct answer – John Ruddell Apr 09 '18 at 09:17
  • ok John, try this: https://codesandbox.io/s/x9q84po70o. how would I update those names in the state? – The Walrus Apr 09 '18 at 14:14
  • @TheWalrus ok cool, yea so you just need to mutate the robot object, assign to the robots array and set that as state. i make a new object signature for the array so that way you aren't mutating state directly. see here https://codesandbox.io/s/olwwj0xmw9 .... if you have any more questions dont hesitate to ask! :) – John Ruddell Apr 09 '18 at 17:34
0

Assuming you are printing name in JSX as below

const { people } = this.state;
return people.map((person, index) => {
    <p
        onClick={() => {
            const newPeople = people.slice();
            newPeople[index] = 'some calculation to find new name';
            this.setState({ people: newPeople });
        }}
    >
        {person.name}
    </p>
});
S4beR
  • 1,872
  • 1
  • 17
  • 33