Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an object value in a form's select field onChange (using React, without Redux)

I'm currently working on a react component with a simple form (no redux, just using react-bootstrap for styling)

I'm pulling data from a database in the following form:

[
  {
    "id":"123",
    "name":"Amy Pond",
    "age":"22",
    "reputation":22000
  },
  {
    "id":"124",
    "name":"Clara Oswald",
    "age":"24",
    "reputation":35000
 }
 ...
]

and putting it into an object:

let userlist = [];
userlist = addUsers(this.state.users);

I used map to populate a dropdown based on this data, and can correctly set the state of the user to the selected one from the drop down:

<FormControl
   id = "user"
   componentClass="select"
   onChange={this.handleChange}
>
   {userlist.map((r , i) =>
     <option
       key={i}
       value={r.name}>
       {r.name}
     </option>
  )}
</FormControl>

using handleChange()

handleChange(event) {
  this.setState({
    value: event.target.value,
    // reputation: ???? // here's where I'm running into issues
    // age: ???????  // and here
});

My problem is, I need the user's age and reputation in the handleChange function to set their states accordingly. I've tried passing just r instead of r.name but I get [object Object] back.

console.log ("Handle Change Value: " + event.target.value);

if I try event.target.value.name I get undefined back.

The only thing that has sort of worked so far, is using JSON.stringify, but I feel like that's not the right way to do this. I've also thought about just searching through the objects once I've gotten just the name, but if there was a lot of objects I think that would be extremely inefficient? I'm also not sure how to do that.

Can anyone please help me find a way to pass these two extra values so I can set the state? Is map even the best way to create the options? I honestly feel like this is such a simple thing, but I'm still new to react and I've been struggling with this for far too long!

Any ideas / changes / comments / way to make this better would be much appreciated! I realize that perhaps using something like redux-form would make this easier, but I'm hoping there's a simple way to do it without that just for now.

Edit: onChange should have been set to onChange = {this.handleChange}, just pasted the wrong code from my attempts to troubleshoot. I'm binding this in the constructor:

constructor(props) {
  super(props);
  ...
  this.handleChange = this.handleChange.bind(this);
}
like image 396
Tori Henri Avatar asked Jan 08 '18 22:01

Tori Henri


People also ask

How do you get the select onChange value in React?

To fetch the selected value from the select element, you can use the onChange event handler prop. Just like the input or textarea elements, you can use the onChange event handler to get the value from the event object. Now, make this select input element controlled by using the state to pass the value.

How do you handle onChange event in React select?

To handle the onChange event on a select element in React: Set the onChange prop on the select element. Keep the value of the selected option in a state variable. Every time the user changes the selected option, update the state variable.

How do you get value of inputs onChange when they are inside map functions?

map((item, index) => ( <div> {item.name} <input key={index} value={this. state. objects[index]} onChange={this. handleChange.


1 Answers

Use the user ID as the value in each option, then in handleChange find the user in your userlist to access all the user's properties:

<FormControl
   id = "user"
   componentClass="select"
   onChange={this.handleChange.bind(this)}
>
   {userlist.map((r , i) =>
     <option
       key={i}
       value={r.id}>
       {r.name}
     </option>
  )}
</FormControl>

handleChange(event) {
  const userId = event.target.value;
  const user = userlist.find(u => u.id === userId);
  this.setState({
    value: user
  });
}

Also, the way you are passing the onChange property might cause issues. It's hard to tell without seeing all your code, but make sure that you pass in a reference to your handleChange function (see above in my answer) rather than calling it right there (as in your question: onChange={this.handleChange()}, unless your this.handleChange function returns a function).

like image 54
forrert Avatar answered Sep 29 '22 13:09

forrert