Is it incorrect to store state like this?
const handleChange = (e) => {
const { name, value } = e.target;
setState((state) => ({
...state,
[name]: value,
}));
};
Nope, not at all, in fact, it is often the preferable pattern for state updates.
Any time your state update depends on the previous state, i.e. the classic counter example, or in your case, when there is nested state, you should use a functional state update to update from the previous state instead of the state from the previous render cycle.
Additionally, am I using setState incorrectly in my handler function?
In most cases I've seen state declared and updated like this which is
obviously easier to read:
const [count, setCount] = useState(0);
setCount(count + 1)
I see no issue with your state update logic in the handler. In this count
example it would (should) be considered incorrect to update a count like this. See this codesandbox demo that attempts to show the issue between non-functional and functional state updates.
The correct state update should be setCount(count => count + 1)
But I have a lot of state and didn't think it would be a good idea to
have multiple setState hooks.
Is there a better way to do this? What I currently have just feels
wrong.
When it comes to form inputs and state I think it makes sense to have a single flat object. There isn't really a right or wrong answer in general though when it comes to using a single useState
hook with "complex" state shape, or to use a single useState
hook for each "chunk" of state. It's an opinionated answer, mostly do what makes sense for a specific use-case.
Generally though I'd say if a set of values are even loosely related then perhaps it makes sense to store them in a common object, but this is my opinion.
A potential issue I see with your imported data though is the chance that you may inadvertently overwrite some key-value pairs by the use of the Spread syntax.
export const OriginState = {
...info,
...images, // <-- could overwrite values from info
...text, // <-- could overwrite values from info and images
};