This page will show you how to update Objects or Array nested index or property.
ARRAYS - Replace Array with New Array
The following Code replaces the current value of uploadFiles with a new array.
const [uploadFiles, setuploadFiles] = useState([])
const handleInputFile = (e) => {
setuploadFiles(uploadFiles => [...uploadFiles, ...e.target.files]);
console.log(`LINE 83 uploadFiles=`, uploadFiles);
}
<input type='file' name='upload' ref={uploadButton} style={{display: 'none'}} value="" onChange={handleInputFile}/>
Resource: https://stackoverflow.com/a/75174741
ARRAYS - Update Index
To update the index values of an array, you first must create a temporary copy of the state value, update the state with the new temp array or you can use the spread operator
Nested Array With Objects update Index Version 1
Source: /g/xampp8/htdocs/laravel/StudentTodo/StudentTodoV2/LogForm.jsx
1. Declare the useState variable:
const [Tasks, setTasks] = useState([]);
2. or Update via form input:Note: this is form a .map loop, hence the index
<textarea className="form-control" placeholder="Type Your Answer Here"
//onChange={e => setTasks( [...Tasks, ...[index] = {...log.story = e.target.value } ])}
onChange={e => handleChange(index, 'log', e.target.value)}
value={typeof task.log!="undefined" ? task.log.story: ''}
>
3. To update the story new value use this function:
function handleChange(index, property, value) {
const new_tasks = [...Tasks]; // copy the array
const new_task = { ...Tasks[index] }; // copy the array item to change
new_task[property].story = value; // set the new value
new_tasks[index] = new_task; // assign the new item to the copied array
setTasks(new_tasks); // return a new data object
}
4. Data Structure: Array with Object that is Fetched Data Example for step 2.
const exampleAPIArray = [
{
id: 1,
task: "go to school",
point: 1,
log: {
id: 1,
story: "this is the response to my go to school task"
}
},
{
id: 2,
task: "Do my homework",
point: 1,
log: {
id: 2,
story: "this is the response to my homeowork task"
}
}
];
Bonus:
the following code will add/push/increment/append to the array:
<textarea className="form-control" placeholder="Type Your Answer Here"
onChange={e => setTasks( [...Tasks, ...Tasks[index].log.story = e.target.value ])}
value={typeof task.log!="undefined" ? task.log.story: ''}
>
Same as above:
<textarea className="form-control" placeholder="Type Your Answer Here"
onChange={e => setTasks( [...Tasks, Tasks[index].log.story = e.target.value ])}
value={typeof task.log!="undefined" ? task.log.story: ''}
>
ARRAYS WITH OBJECTS Version 2
To update an object in an array index, you will have to loop through all array elements and when you have found a match, update the values of the object property.
1. Declare the Array with objects, Here I have an array for fields a form
const [formFields, setFormFields] = useState<any>([
{ title: "First Name", name: "fname", value: "John" },
{ title: "Last Name", name: "lname", value: "Doe" },
{ title: "Phone", name: "phone", value: "213-555-1212" },
]);
2. Listen to the on change event, I am using Ionic for this example:
<form onSubmit={submitRecipientInformation}>
<IonList>
{formFields.map((field, index) => {
return (
<IonItem key={index}>
<IonInput
required
value={field.value}
name={field.name}
label={field.title}
labelPlacement="floating"
placeholder={`Enter ${field.title}`}
onIonInput={(e)=>updateState(index, 'value', e.target.value)}
/>
</IonItem>
);
})}
</IonList>
</form>
3. Declare the UpdateState function, you can this function whatever you want:
const updateState = (index:number, property:string, value:any) => {
setFormFields(
formFields.map((item:any, i:number) =>
i === index ? { ...item, [property]: value } : item
)
);
};
Update Array Index Version 3:
Example:
// UPDATE ARRAY INDEX VALUE
//https://dev.to/andyrewlee/cheat-sheet-for-updating-objects-and-arrays-in-react-state-48np
// OPTION 1. create a new temp variable
//let showTextBoxTempArr = showTextBox; //[0,0,0,0]
// showTextBoxTempArr[task] = emoji;
//setShowTextBox(showTextBoxTempArr);
// OPTION 2 - USE THE SPREAD OPERATOR
const tempArr = [...showTextBox];
console.log(`LINE 141 tempArr=`, tempArr);
setShowTextBox(tempArr);
setTestState('UPDATED');
OBJECTS
The best way to update an object's property is to use the spread operator.
Inline in the JSX Code:
onChange={ev => setLog({...log, story: ev.target.value})}
example using a textarea to update log.story
const [log, setLog] = useState({
id: null,
story: '',
task_rating: '2222',
log_date: new convertTimeZone(Date()) // SET TODAY"S DATE
})
<textarea
required="required"
className="form-control"
id="exampleFormControlTextarea1"
rows="3"
name="story"
value={log.story}
onChange={ev => setLog({ ...log, story: ev.target.value })}
></textarea>
Resources:
- https://beta.reactjs.org/learn/updating-arrays-in-state
- https://forum.freecodecamp.org/t/how-change-react-state-if-it-is-multidimensional-array-and-contain-objects/564532
- https://dev.to/andyrewlee/cheat-sheet-for-updating-objects-and-arrays-in-react-state-48np