I have an object array that I'm outputting to a form of inputs. These inputs need to be updated, the values rendered to show the changes. I'm able to console the key and new value but the error I receive is that metafields.map
is not a function.
My code is as follows:
class EditMetafields extends React.Component {
constructor(props) {
super(props);
this.state = { metafields: [] }
}
componentDidMount() {
// retrieving data from the db to populate metafields
metafields = [
{id: 0, key: "key0", value: "value0"},
{id: null, key: "keyNull", value: "valueNull"},
{id: 2, key: "key2", value: "value2"},
]
this.setState({ metafields: metafields });
}
render() {
const { metafields } = this.state;
const formFields = metafields.map((props) =>
<TextField
key={props.id}
label={props.key}
id={prop.id}
value={props.value}
changeKey={props.id} onChange={(val) =>{
console.log(props.key, val); //returns accurate output i.e. "key0 value0a" when 'a' key pressed
this.setState({ metafields: { ...this.state.metafields, [props.key]: val } }) //TypeError: metafields.map is not a function after 'a' key pressed
}
} />
);
return (
<Page>
<Form>
{formFields}
</Form>
</Page>
)
}
}
When it was an array of object containing a single key/value pair I was able to pair and change without issue but now that I have to attach ids and more to the object React gets upset with Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
I need to work with objects containing id, namespace, key, and value and output each object to a input within a form that can be updated but I'm not sure if I'm using React properly by assigning metafields to props. Links to relevant articles or a point in the right direction would be much appreciated!
As Brian mentioned, this line:
this.setState({ metafields: { ...this.state.metafields, [props.key]: val } })
changes the metafields
state variable into an object. What I think you're trying to do, is update an element's value in the metafields
array, based on key.
To accomplish this, you should use map
and use the callback variant of setState
(since you're depending on the previous state of metafields
):
this.setState(prevState => {
return { metafields: prevState.metafields.map(metafield => {
if (metafield.key === props.key) {
metafield.value = val;
}
return metafield;
})};
});
This code will update the correct element in the metafields
array with the new value.