How do I update states `onChange` in an array of object in React Hooks
Here is how you do it:
// sample data structure
/* const data = [
{
id: 1,
name: 'john',
gender: 'm'
}
{
id: 2,
name: 'mary',
gender: 'f'
}
] */ // make sure to set the default value in the useState call (I already fixed it)
const [data, setData] = useState([
{
id: 1,
name: 'john',
gender: 'm'
}
{
id: 2,
name: 'mary',
gender: 'f'
}
]);
const updateFieldChanged = index => e => {
console.log('index: ' + index);
console.log('property name: '+ e.target.name);
let newArr = [...data]; // copying the old datas array
// a deep copy is not needed as we are overriding the whole object below, and not setting a property of it. this does not mutate the state.
newArr[index] = e.target.value; // replace e.target.value with whatever you want to change it to
setData(newArr);
}
return (
<React.Fragment>
{data.map((datum, index) => {
<li key={datum.name}>
<input type="text" name="name" value={datum.name} onChange={updateFieldChanged(index)} />
</li>
})}
</React.Fragment>
)
How to update state with usestate in an array of objects?
You can safely use javascript's array map functionality since that will not modify existing state, which react does not like, and it returns a new array. The process is to loop over the state's array and find the correct id. Update the done
boolean. Then set state with the updated list.
const toggleDone = (id) => {
console.log(id);
// loop over the todos list and find the provided id.
let updatedList = state.todos.map(item =>
{
if (item.id == id){
return {...item, done: !item.done}; //gets everything that was already in item, and updates "done"
}
return item; // else return unmodified item
});
setState({todos: updatedList}); // set state to new object with updated list
}
Edit: updated the code to toggle item.done
instead of setting it to true.
Update object in array using useState and a button
You can update a user by first getting the index of this user in the array, then update the element in the array, then return the array :
const update = (e) => {
setUsers(users => {
const index = users.findIndex(item => item.name === user.name);
if (index === -1) {
return […users, user];
}
users[index] = user;
return users;
}
}
how to use onChange on array of objects to add data in ReactJS
From your code, I'm guessing user
is an object instead of an array. You are initializing the user as an array even though it should be an object (assuming from the use of user
word here, i.e singular). I made the following changes:-
- Initialize user as an object.
- Use spread operator and add new property
user_name
ormobile_number
as needed to update the state.
The below code should work
function ContactForm() {
const [user, setUser] = useState({});
const submitForm = () => {
console.log(user);
};
return (
<div>
<input
type="text"
placeholder="name"
onChange={(e) =>
setUser({...user, user_name: e.target.value });
}
value={user.user_name}
/>
<input
type="text"
placeholder="mobile"
onChange={(e) =>
setUser({...user, mobile_number: e.target.value })
}
value={user.mobile_number}
/>
<button onClick={submitForm}>Submit</button>
</div>
);
}
Best ways to update state array object using React Hooks?
Doing this is a state mutation!!
setData(prevState => {
let obj = prevState.find(o => anycondition);
if(obj !== undefined) {
obj.name = "Demo"; // <-- state mutation
}
return [...prevState];
})
Should always shallowly copy current state that is being updated
setData(prevState => {
return prevState.map(el => <condition> ? { // <-- map state to new array
...el, // <-- copy element
name: "Demo", // <-- write new property
} : el);
})
If you need to do any calculations within the map callback, give the callback a normal function body and add any logic needed.
setData(prevState => {
return prevState.map(el => { // <-- map state to new array
// any mapping logic
...
if (<condition>) {
// any other logic
...
return {
...el, // <-- copy element
name: "Demo", // <-- write new property
}
} else {
return el;
}
});
})
How to update an array of objects with clickHandler and useState in Reactjs
The initial value of votes is array. But you are treating it as object.
const newClicks = {
...votes,
vote: votes[1].vote + 1
};
You should do something like this.
const newClicks = [...votes];
let newVote = { ...newClicks[1] };
newVote.vote++;
newClicks[1] = newVote;
setVotes(newClicks);
Enjoy!
useState to update array of objects nested inside object
push
mutates the array, you should create a new array like so:
setGroupState({
...groupState,
content: [...groupState.content, {test: 'test'}],
});
Related Topics
Is Performing a Mapping Operation Without Using Returned Value an Antipattern
Adding Prototype to JavaScript Object Literal
What the Difference Between .Click and .Change on a Checkbox
How to Use Blob Url, Mediasource or Other Methods to Play Concatenated Blobs of Media Fragments
What Is Property in Hasownproperty in JavaScript
Clearing Localstorage in JavaScript
How to Remove Element from Array in Foreach Loop
Disabling the Long-Running-Script Message in Internet Explorer
Advanced JavaScript: Why Is This Function Wrapped in Parentheses
Paste an Image from Clipboard Using JavaScript
Copy to Clipboard in Chrome Extension
How to Get the Exact Local Time of Client
What's Pros and Cons: Putting JavaScript in Head and Putting Just Before the Body Close
ASP.NET MVC 3 Razor: Include JavaScript File in the Head Tag