I am trying to change the properties of objects inside of an object and trying to add new properties to these objects but keeping the old values.
I can’t find out how to get the right nested object by index, not id because the id can be different from the .map index.
This is what I got so far, the Object names are for testing purposes only and maybe the “updateNestedObject” can be run in the parent?
Thank you in advance and sorry if this is a noob question.
Neval
import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet, Button, Alert } from 'react-native';
function ObjectScreen() {
const [state, setState] = useState({
id: 1,
name: 'Test Object',
nested: [
{
id: 1,
title: 'Object 1',
},
{
id: 2,
title: 'Object 1',
}
]
});
function editNested({nestedObject, index, setState}) {
const updateNestedObject = () => {
setState(prevState => ({
nested: [
...prevState.nested,
[prevState.nested[index].comment]: 'Test Comment',
},
}));
}
return (
<View>
<Text>{object.title}</Text>
<TextInput
style={styles.input}
name="comment"
onChangeText={updateNestedObject}
/>
</View>
);
}
return (
<>
<Text>{state.name}</Text>
{ state.nested.map((nestedObject, key)=>{
return (
<editNested key={key} index={key} object={object} nestedObject={nestedObject}/>
)
})}
</>
)
}
const styles = StyleSheet.create({
container: {},
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
},
});
export default ObjectScreen;
Advertisement
Answer
There were few issues:
JSX component name
editNestedshould start with a capital letter.And
editNestedcomponent should be on its own function, should not define inside another component which caused yourTextInputto lose focus after each render cycle.The
setStatecall should be changed like below:
const updateNestedObject = (text) => {
setState((prevState) => ({
...prevState,
nested: prevState.nested.map((item) =>
item.id === nestedObject.id ? { ...item, value: text } : item
)
}));
};
Try the code below:
import React, { useState } from "react";
import { View, TextInput, Text, StyleSheet, Button, Alert } from "react-native";
function EditNested({ nestedObject, setState }) {
const updateNestedObject = (text) => {
setState((prevState) => ({
...prevState,
nested: prevState.nested.map((item) =>
item.id === nestedObject.id ? { ...item, value: text } : item
)
}));
};
return (
<View>
<Text>{nestedObject.title}</Text>
<TextInput
style={styles.input}
onChangeText={updateNestedObject}
value={nestedObject.value}
/>
</View>
);
}
function ObjectScreen() {
const [state, setState] = useState({
id: 1,
name: "Test Object",
nested: [
{
id: 1,
title: "Object 1",
value: ""
},
{
id: 2,
title: "Object 1",
value: ""
}
]
});
console.log(state);
return (
<>
<Text>{state.name}</Text>
{state.nested.map((nestedObject, key) => {
return (
<EditNested
key={key}
nestedObject={nestedObject}
setState={setState}
/>
);
})}
</>
);
}
const styles = StyleSheet.create({
container: {},
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10
}
});
export default ObjectScreen;
Working Demo