Reputation: 1054
I am building a ReactJS application, and I need to store data in this way:
this.state = {
user: {
name: "",
surname: "",
age: "",
...
instruments: [],
}
}
The instruments
state needs to contain several objects, with properties name
and experience
. An example:
instruments: [
{
name: 'Bass guitar',
experience: 7,
},
{
name: 'Drums',
experience: 1,
}
...
]
I'm new to React, so far I have been able to save data in similar arrays by doing this:
musicListenChange(val){
let musicListenArray = this.state.user.music_listen ? this.state.user.music_listen : [];
musicListenArray.push(val.value);
this.setState({user: {...this.state.user, music_listen: musicListenArray}});
}
However, when I try to save an object with the following code I receive an error:
saveInstrument(){
// save current instruments state in array, or create an empty one
let array = this.state.user.instruments ? this.state.user.instruments : [];
// in this.state.instruments I saved a temporary copy of the selected instrument, put it in the array
array.push(this.state.instruments);
this.setState({user: {...this.state.user, instruments: array }});
console.log('instrum. state: ', this.state.user.instruments);
}
Error code
Uncaught Error: Objects are not valid as a React child (found: object with keys {name, experience}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `EditProfile`.
My EditProfile render part for the instruments
<div className="container-tags">
{this.state.user.instruments ? this.state.user.instruments.map(function (instrument, index) {
return <button className="btn btn-default">{instrument}</button>;
}) : <div></div>}
</div>
Any idea on how to fix this? Thanks
Upvotes: 4
Views: 27925
Reputation: 104529
Instrument is an object, and you are trying to render it, use the specific value that you wants to render, Try this:
musicListenChange(val){
let user = this.state.user;
user['music_listen'] = val.value;
this.setState({user: user);
}
saveInstrument(){
let user = this.state.user;
user['instruments'] = user['instruments'] ? user['instruments'] : [];
user['instruments'].push(this.state.instruments);
this.setState({user: user});
}
In render function use this:
{this.state.user.instruments ?
this.state.user.instruments.map((instrument, index) => {
return (<button className="btn btn-default">{instrument.name}</button>)
})
:<div/>
}
Upvotes: 5
Reputation: 3291
The problem is here:
<div className="container-tags">
{this.state.user.instruments ? this.state.user.instruments.map(function (instrument, index) {
return <button className="btn btn-default">{instrument}</button>;
}) : <div></div>}
</div>
When realising that instrument
is a JavaScript object (you said that your instruments
array contains objects with structure {name: "string", experience:"string"}
), the error message becomes clear: you are trying to insert an object as a child of the <button>
element, which is not allowed, since React has no idea how to display an object. If you used instrument.name
or instrument.experience
instead (which are strings), your code will work.
Upvotes: 2