Reputation: 228
I've recently started to try to learn React hooks, but for the life of me I can't figure out some things, like multiple state management, I've found a few example but nothing seems to be in a specific pattern. I'm not even sure how you're supposed to define your states if there's more than 2 and you want to change them individually, should it be like this:
const [slides, setSlides] = useState([])
const [currentSlide, setCurrentSlide] = useState(0)
const [tagName, setTagName] = useState([])
Or like this:
const [states, setStates] = useState({
slides: [],
currentSlide: 0,
tagName: []
})
And if both or the second one is viable (honestly I would prefer the second one since its less repetitive in calling useState and closer to the standard state meta) how could one go about changing states in such a example? I couldn't really find anything on this, so what I tried was this:
useEffect(() => {
Object.entries(Slides).forEach(slide => {
setStates(prevState => ({ slides: [...prevState.slides, slide[1]] }))
})
}, [])
And I messed around with it a bunch trying to get some decent results but I couldn't get it to work properly.
Any ideas of what I'm doing wrong? And on which one of these to methods of best practice?
Thanks!
Upvotes: 1
Views: 483
Reputation: 104379
In terms of updating state, first template is much easy and simple, because each stateUpdate function will be responsible for updating single value, that can be obj/array/int/bool/string
. Another thing is, to access each value of the state (it will be an object), you need to write states.slides
, states.tagName
etc.
With first case, state update will be simply:
// only value in case of int/string/bool
updateState({ [key]: value }) or updateState(value);
But in second case, state will be an object with multiple keys, so to update any single value you need to copy the object, then pass the updated key-value. Like this:
updateState({
...obj,
[key]: newValue
})
To update the slides array:
updateState(prevState => ({
...prevState,
slides: newArray
}))
Handling complex state update:
Use useReducer to handle the complex state update, write a separate reducer function with action types and for each action type so the calculation and return the new state.
For Example:
const initialState = { slides: [], tagName: [], currentSlide: 0 };
function reducer(state, action) {
switch (action.type) {
case 'SLIDES':
return { ... };
case 'TAGNAME':
return { ... };
case 'CURRENT_SLIDE':
return { ... }
default:
throw new Error();
}
}
function Counter({initialState}) {
const [state, dispatch] = useReducer(reducer, initialState);
....
}
Upvotes: 1
Reputation: 3551
It is true that the useState
hook can become quite verbose when dealing with complex state object.
In this case, you can also consider using the useReducer
hook.
I would recommend the reading of this article about useState
vs useReducer
.
Upvotes: 1