React Hooks useState() with Object
You can pass new value like this:
setExampleState({...exampleState, masterField2: {
fieldOne: "a",
fieldTwo: {
fieldTwoOne: "b",
fieldTwoTwo: "c"
}
},
})
Best practice for React useState with objects?
You could do that, but it's not what the official React docs do or recommend. It's still a working and valid approach.
If you find yourself using a state object because there's a lot of state, or managing interactions gets complicated, it might be a good time to consider using a reducer with useReducer
. You can move the boilerplate and logic out of the immediate call-site and better retain overview over the relationship between properties of you state object. With a reducer you‘d just write dispatch({ type: "SET_NAME", name: "Daniel" })
.
Having all the code that modifies your state in one place (the reducer) allows you to better reason over actions such as resetting the state.
The dispatch function returned by useReducer
is also stable and well suited to be passed to child components, making it easier to refactor your component into smaller ones.
How do I update 2 objects with React Hook useState
You are mutating your state object. Even though you create a copy temp
of the message
state, you are mutating the nested properties. You necessarily need to also shallow copy all nested state you are updating.
I would suggest using a functional state update to access the previous messagestate, and use a
switchstatement to cover the different cases on the
name` value, returning the next state value for each one. Notice that each level of nested state is shallow copied before it's updated.
const [message, setMessage] = useState({
Features: { Active: false },
General: { FileTimeout: 0, ZipDepth: 0 }
});
const handleInput=e=>{
const { name, value } = e.currentTarget;
setMessage(message => {
switch(name) {
case 'active':
if (value === 'on') {
return {
...message, // shallow copy of state
Features: {
...message.Features, // shallow copy nested state
Active: true,
},
};
} else {
// ? return some new state
}
case 'timeout':
return {
...message, // shallow copy of state
General: {
...message.General, // shallow copy nested state
ZipDepth: 5,
},
};
case 'zipdepth':
return {
...message, // shallow copy of state
General: {
...message.General, // shallow copy nested state
FileTimeout: 7,
},
};
default:
return message; // no update, return current state
};
});
}
update an object with useState hook in React
As for any modification you want to do on a useState variable, you must use an arrow function inside of the "set" function.
You can do something like that :
setBoard((currentBoard)=> {
currentBoard.lanes[0].cards = [...currentBoard.lanes[0].cards, whateverCardYouWantToAdd ]
return {... currentBoard} //necessary to create a new object because else the hook won't be updated
})
React Hooks useState() with an Array of Object
You can try this and hope it may help you for compoTwo.
Note: You can also set the todo prop value as the initial value of useState.
const compoTwo = ({ todo, todos, setTodos }) =>{
const [a, setA] = useState("")
const [b, setB] = useState("")
const [c, setC] = useState("")
const handleChange = (e) => {
const { name, value } = e.target;
setTodos((prevState) => {
const temp = [...prevState];
const find = temp.find((res) => res.id === todo.id);
if (find) {
find[name] = value;
return temp;
} else {
return prevState;
}
});
};
return(
<>
<InputText
value={a}
name="a"
onChange={(e)=>setA(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field A"
/>
<InputText
value={b}
name="b"
onChange={(e)=>setB(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field B"
/>
<InputText
value={c}
name="c"
onChange={(e)=>setC(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field C"
/>
</>
)
}
React useState - update all object values to true
The problem you are facing is that you are mutating the state object, which means that at the end, prevState === nextState
and React bails out of rendering. An option is to use a new object and copy the props like this, using the same combo of Object.keys
and forEach
but adding an extra step:
setState(prevState => {
const nextState = {}
Object.keys(prevState).forEach(key => {
nextState[key] = true
})
return nextState
})
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;
}
}
React hook use class object as useState
Your example illustrates the case of "prop drilling".
Prop drilling (also called "threading") refers to the process you have to go through to get data to parts of the React Component tree.
Prop drilling can be a good thing, and it can be a bad thing. Following some good practices as mentioned above, you can use it as a feature to make your application more maintainable.
The issue with "prop drilling", is that it is not really that scalable when you have an app with many tiers of nested components that needs alot of shared state.
An alternative to this, is some sort of "global state management" - and there are tons of libraries out there that handles this for you. Picking the right one, is a task for you /p>
I'd recommend reading these two articles to get a little more familiar with the concepts:
- Prop Drilling
- Application State Management with React
React: problem with putting object into useState
There were two issues in your code.
- In
TraningForm
form should be updated wheneverobj
changes. Need to add auseEffect
hook below.
useEffect(() => {
setForm(obj);
}, [obj]);
- In
EditObj
method there was a mistake. It should be...item
instead of...prevTraining
.
const EditObj = (obj) => {
setTraining((prevTraining) =>
prevTraining.map((item) => {
if (item.id == obj.id)
return { ...item, date: obj.date, passed: obj.passed };
return item;
})
);
};
Code Sandbox
Related Topics
How Does the (Function() {})() Construct Work and Why Do People Use It
Merge JavaScript Objects in Array with Same Key
React Router V6 Navigate Outside of Components
Canvas.Todataurl() Securityerror
Format Date to Mm/Dd/Yyyy in JavaScript
Remove Items from Array with Splice in for Loop
Convert String in Dot Notation to Get the Object Reference
Using Http Rest APIs with Angular 2
When Does Js Interpret {} as an Empty Block Instead of an Empty Object
How to Map More Than One Property from an Array of Objects
Chrome Extension - Sendresponse Not Waiting for Async Function
Accessing Variables from Greasemonkey to Page & Vice Versa