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);
}
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).
It could be a problem with the way you've set your event listener, settings onChange={this.handleChange()}
would cause the listener to fire right away. Using onChange={this.handleChange}
correctly sets the listener.
<FormControl
id = "user"
componentClass="select"
onChange={this.handleChange}>
{userlist.map((r , i) =>
<option
key={i}
value={r.name}>
{r.name}
</option>
)}
</FormControl>
See here for more on events.
You can then use find()
in your event handler to locate the user:
handleChange(event) {
let user = users.find(u => u.name === event.user.name);
this.setState({user: user});
}
you can use option tag attribute and json to encode/decode like this:
<FormControl
id="user"
componentClass="select"
onChange={this.handleChange.bind(this)}
>
{userlist.map((r, i) =>
<option
key={i}
value={r.id}>
{r.name}
data={JSON.stringify(r)}
</option>
)}
</FormControl>;
handleChange(event)
{
if (e.target.options && e.target.selectedIndex) {
const user = e.target.options[e.target.selectedIndex].getAttribute('data');
this.setState({
value: user
});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.