1

Updating state works if the state i am trying to update is outside the users array. But since i am having multiple users i need the state to be inside the objects and update anyway

I keep getting the error TypeError: Cannot read property 'name' of undefined

I've thought of setting state inside of a loop but i was told thats a bad idea.

So [e.target.name]: e.target.value was the only code i could find for dropdowns.

I tried passing id for each of the users but didnt know how to change state using that or what condition to put.

import React, { Component } from 'react'
export default class App extends Component {

  state = {
    users: [
      {
        id: uuid(),
        firstName: 'John',
        lastName: 'Doe',
        favColor: 'None'
      },
      {
        id: uuid(),
        firstName: 'Jane',
        lastName: 'Doe',
        favColor: 'None'
      }
    ]
  }

  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  render() {

    return (
      <div>
        {this.state.users.map((user) => {

          return <div key={user.id}>

            <h1>{user.firstName}</h1>
            <h1>{user.lastName}</h1>

            <form>
              <select 
                  name="favColor" 
                  value={user.favColor} 
                  onChange={() => this.handleChange(user.id)}
              >
                <option value="None" disabled>None</option>
                <option value="Blue">Blue</option>
                <option value="Red">Red</option>
                <option value="Green">Green</option>
              </select>
            </form>

            <h1>Fav Color: {user.favColor}</h1>
            <hr />
          </div>
        })}
      </div>
    )
  }

}

I expect the dropdowns to change state separately for each of the users

4
  • change onChange like this : onChange={(e) => this.handleChange(e) Commented Oct 3, 2019 at 6:29
  • what is the state structure you want? plus e.target.name is the select's name. Commented Oct 3, 2019 at 6:34
  • @rapSherlock that seemed to have removed the error and shows state is updating in the React tools yet doesnt show any change in the UI Commented Oct 3, 2019 at 6:35
  • it because your user state is array Commented Oct 3, 2019 at 6:39

3 Answers 3

2

Your handleChange method is not accepting the correct arguments. If you wish to update one user item in array you will need to create a new updated copy of the array and save back into state

handleChange = (e,id) => {
const updatedUser = {...this.state.users.find(x=>x.id ===id), favColor: e.target.value}
 this.setState({
    users:  [...this.state.users.filter(x==>x.id!==id),updatedUser]
    })
}

...
onChange={(e) => this.handleChange(e,user.id)}

To simplify mutations of state I can recommend taking a look at Immer

And as @JosephD rightly pointed out this won't mantain order so you will need to do something like this.state.users.map(u => u.id === id ? { ...u, favColor: e.target.value } : u)

Here is a codesandbox based on your code: https://codesandbox.io/s/loving-cohen-do56l?fontsize=14

Sign up to request clarification or add additional context in comments.

8 Comments

if i do the above it removes my firstNames and lastNames onChange and makes the Fav Color: go from 'None' (initial state) to just empty
did it correctly find the user by id? what does the shape of updatedUser now look like? Did you check the value of id?
okay so if i console.log(id) onchange it displays one id for the first time only and all the other changes are showing undefined
if I console the state before change it shows the two objects but after change it shows (2) [false, true] and then (2) [false, false]
also thanks Damian for sticking around for an hour and fixing my code, really appreciate it
|
1
  <select 
     name="favColor" 
     value={this.state.favColor} 
     onChange={(e) => this.handleChange(e)}>  // first Change

 handleChange = (e) => {
    this.setState({
     favColor: e.target.value 
    })
  } // Second Change

This will work for you

3 Comments

that seemed to have removed the error and shows state is updating in the React tools yet doesnt show any change in the UI
yaa, because the default value was user.favColor, I edit the answer, try this will work for you
value={this.state.favColor} is wrong i am displaying the users in a loop so it needs to be value={user.favColor}
1

You are updating the state the wrong way;

Your state:

users: [
    { id: 1, ... },
    { id: 1, ... }
]

Your update / intention:

users: [
    { id: 1, ... },
    { id: 1, ... }
]
favColor: color // intention, because you don’t pass event

To update the right way, you need to:

  • pass the event and currentId, to handleChange, of the selected dropdown. Otherwise you cannot know the current user. Also, in your example you don’t pass the event, so you cannot retrieve the information of the dropdown. Causing the name of undefined error.
  • check when id of user matches with id of dropdown and change the value.

This example should work for you.

https://codesandbox.io/s/small-sea-mw08n

3 Comments

Glad i could help, I did some minor edits to make it more clear for you and others.
i revisited that codesandbox after few hours and its a totally different link now. Is that the same on your end?
Sorry, i messed up. I re-used the sandbox for something else. I recreated a sandbox with a new id for this topic. Can you check please?

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.