Je travaille actuellement sur un composant react avec une forme simple (pas de redux, juste en utilisant react-bootstrap pour le styling)
Je extrait des données d'une base de données sous la forme suivante:
[
{
"id":"123",
"name":"Amy Pond",
"age":"22",
"reputation":22000
},
{
"id":"124",
"name":"Clara Oswald",
"age":"24",
"reputation":35000
}
...
]
et le mettre dans un objet:
let userlist = [];
userlist = addUsers(this.state.users);
J'ai utilisé map pour créer un menu déroulant basé sur ces données et je peux définir correctement l'état de l'utilisateur sur celui sélectionné dans le menu déroulant:
<FormControl
id = "user"
componentClass="select"
onChange={this.handleChange}
>
{userlist.map((r , i) =>
<option
key={i}
value={r.name}>
{r.name}
</option>
)}
</FormControl>
en utilisant handleChange ()
handleChange(event) {
this.setState({
value: event.target.value,
// reputation: ???? // here's where I'm running into issues
// age: ??????? // and here
});
Mon problème est que j'ai besoin de l'âge et de la réputation de l'utilisateur dans la fonction handleChange pour définir leurs états en conséquence. J'ai essayé de passer juste r
au lieu de r.name
mais je récupère [object Object]
.
console.log ("Handle Change Value: " + event.target.value);
si j'essaie event.target.value.name
, je récupère undefined
.
La seule chose qui a fonctionné jusqu’à présent, est d’utiliser JSON.stringify, mais j’ai l’impression que ce n’est pas la bonne façon de procéder. J'ai aussi pensé à chercher dans les objets une fois que j'ai reçu le nom, mais s'il y avait beaucoup d'objets, je pense que ce serait extrêmement inefficace? Je ne sais pas non plus comment faire cela.
Quelqu'un peut-il m'aider à trouver un moyen de passer ces deux valeurs supplémentaires afin de pouvoir définir l'état? La carte est-elle même le meilleur moyen de créer les options? Honnêtement, j’ai l’impression que c’est une chose si simple, mais je suis encore novice et j’ai du mal à le faire depuis trop longtemps!
Toutes les idées/modifications/commentaires/moyens d'améliorer cela seraient très appréciés! Je me rends compte que l’utilisation de quelque chose comme redux-form faciliterait cela, mais j’espère qu’il existe un moyen simple de le faire sans cela pour le moment.
Edit: OnChange aurait dû être défini sur onChange = {this.handleChange}
, juste collé le mauvais code de mes tentatives de dépannage. Je lie ceci dans le constructeur:
constructor(props) {
super(props);
...
this.handleChange = this.handleChange.bind(this);
}
Utilisez l'ID utilisateur comme valeur dans chaque option
, puis dans handleChange
, recherchez l'utilisateur dans votre userlist
pour accéder à toutes ses propriétés:
<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
});
}
La manière dont vous passez la propriété onChange
peut également causer des problèmes. Il est difficile de dire sans voir tout votre code, mais assurez-vous de passer une référence à votre fonction handleChange
(voir ci-dessus dans ma réponse) plutôt que de l'appeler ici (comme dans votre question: onChange={this.handleChange()}
, à moins que votre fonction this.handleChange
ne renvoie un une fonction).
Cela pourrait être un problème avec la façon dont vous avez défini votre écouteur d'événement. Les paramètres onChange={this.handleChange()}
provoqueraient le déclenchement immédiat de l'écouteur. Utiliser onChange={this.handleChange}
définit correctement le programme d'écoute.
<FormControl
id = "user"
componentClass="select"
onChange={this.handleChange}>
{userlist.map((r , i) =>
<option
key={i}
value={r.name}>
{r.name}
</option>
)}
</FormControl>
Voir ici pour plus d'informations sur les événements.
Vous pouvez ensuite utiliser find()
dans votre gestionnaire d'événements pour localiser l'utilisateur:
handleChange(event) {
let user = users.find(u => u.name === event.user.name);
this.setState({user: user});
}
vous pouvez utiliser option tag attribut et json pour encoder/décoder de la manière suivante:
<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
});
}
}