Combine useReducer with useState in the same component - reactjs

I use react hooks useReducer that contains my state, let's say I have 3 state fields - a,b and c.
Those fields tie together and mostly change together - so the reducer function is cohesive.
If I have different state field d that is not cohesive to the other state - should I use both useState (for d) and useReducer (for a,b and c) at the same component or it's better to use the same reducer function? Moreover - if I have more fields like d that changes in similar places - should I use 2 seperate reducers?
What is the best practice for this case?

My advice would be use both useState and useReducer, given useReducer is just an abstraction around useState.
Just like you wouldn't try to cram all the state of the component into one useState hook, you likely should also avoid doing that for useReducer.

I tend to try and abstract the useReducer to a global context and use useContext in conjunction with the reducer to get my application state. However, sometimes it makes sense to use useContext and useState if the component has an internal state. That being said, I don't think there are any hard and fast rules for hooks at the moment, so I would read up more and make the best choices for your team. That being said, I do agree with what IliasT said about cramming state into one useState. If you go with the useState hook use one for each piece of state and don't try and make an object that controls the state.

Related

Is it fine if useContext has many useState in React

I am working using useContext in React. Today, I recognized that I am using too many useState in useContext. I was looking for the answer, but I could not find it.
I know it is a silly question, but please answer my question if possible.
Thank you.
Thank you for the answers to my question. So, I understand that if there will be many states in useContext, it is a good way to use useRedux.
This is my opinion. I think there is no such thing as too much as long as your states are relevant with what you are doing. It depends on what is your purpose when using the createContext. But make sure to organize them well so that they are still modular and not mixed with other context of states.
For me, I draw a simple borderline where if I'm only making some one-off reusable components that need control from far away (e.g. Dialog which can be toggled by deeply nested button), then I should create a context that has just enough states for that component. Whereas if I want to store some states which I want to access from multiple places, especially if it is related to business logic, then I prefer to use Redux instead.
I think useContext and useState are different functions:
useContext: This is a hook that returns values from the context that has been kept. Any change in values causes the react component where this hook is placed to rerender.
useState: a hook that declares the react component's state.
I think I understand what you mean when you say you declare many states in the context. Some best practices you need to consider are:
Using useReducer hook to group & manage the change of states. It makes it easier to control the changing of states. It is obvious that the state shifts with each individual action.
You need to review the total state that is declared. Only keep states that need to be shared in that context.
Refer: read more in react js docs about context api & declare a state in react component.

React Hooks useReduce or useState

I have a form with 30 fields and all those fields are a template from a value in a dropdown, if I change the value of the template I will end up creating a custom template.
So the action is:
When we are changing a value from the form, the template will change in custom template
As you can see there are some logic that come up and down and I'm worried about the multiple setState declaration and call. Should I use useReducer or useState?
From the useReducer documentation:
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.
You should use the useReducer to manage you complex form, otherwise you'll end up having many useState and a many useEffects to update every other state when one of those useState changes. In this case useReducer is definetevely the best option.
In this way all your UI elements will be a visual representation of the useReducer state, so any value change in a field must trigger an action to update the state and then the UI.
You can also try using an existing library like react-hook-form, but this choise is up to you and depends on your requirements.

The order of react hooks

I am trying to understand how React hooks work reading official docs:
https://reactjs.org/docs/hooks-rules.html
And there they say that react relies on the order hooks are called. I still don't get why the order is of importance and why a hook placed in a conditional will cause bugs, could anyone explain?
Particularly this sentence makes me confused:
React wouldn’t know what to return for the second useState Hook call
why?? Does react somehow binds useState with useEffect?
Then, this question:
So how does React know which state corresponds to which useState call?
From my understanding there is only one state, so why they are talking about states (plural)?

How to use React Hooks with multiple API calls?

I'm trying to understand how to use React Hooks in my new project and I'm looking for some guidance as I didn't find clear answer.
I have a form that requires data from 3 separate API calls. Currently I have created 3 hooks like useGetDataSource1, useGetDataSource2 and useGetDataSource3 that wrap API calls with useEffect. Also I've encapsulated usage of these 3 hooks in additional hook called useGetSettings with additional useEffect to separate this logic from form code. Is that correct? Or maybe I should create only one hook useGetSettings and keep data source logic separated in plain JavaScript functions?
I want to save data from this form when user presses Submit button. Should I use useCallback for it or I shouldn't use any hook at all? Currently I've created 4 hooks just like with getting data, but without any useEffect/useCallback.
useEffect is meant to control the side effects in functional components, in most cases; you shouldn't need to have a useEffect hook inside a hook that encapsulates another hook that uses useEffect
Most hooks are meant to set and get, for example:
useState hook can be used like:
const [count, setCount] = useState(0);
count is the variable you use to get the current state value
setCount is the setter; where you set the state value
Hooks are cool but do not hookify everything, check this article:
React hooks: not magic, just arrays
If you'd like to outsource complicated logic to another file and call it a hook; technically you may, but it's best to just call that functional, object oriented programming with separation of concerns, write tiny functions that does one thing, one thing only and does it perfectly, this way; when your code grows, your tiny functions will be easy to maintain with the power of emergence.

Why use useState over this.state?

I have been learning React hooks lately and I am currently facing useState. I know this is a way to use state in functional components but I wonder what the real benefits are above using a React.PureComponent with this.state?
Is it really bad practice now to use a PureComponent instead of useState or useEffect? Does this make the app "faster"?
I know this question sounds dumb because useState is the new kid on the block but I just need a valid reason to refactor my old components into this new pattern?
Edit: I've been using hooks for a while now and like them a lot (changed my opinion), however it increases the learning curve and there are pitfalls:
Good stuff:
Not wrapping your component in Higher Order Components (looks cleaner and sometimes order of HOCs can cause issues)
Composability and re-use becomes easy - splitting code out to custom hooks is second nature. Also reduces argument for adding other abstraction concepts around state management, data fetching, utilities since hooks can do it all.
No confusion around this (easily avoided with arrow functions in classes tbh)
Some components come out cleaner and terser (but some especially with lots of event listeners can turn into a hot mess without careful architecture and knowledge of how to make the best use of hooks)
Some libraries are hook compatible or hook focused only these days (not a "good" thing but an argument for use)
Bad stuff:
Larger API surface area/knowledge - memo, useCallback, useMemo, useRef, useEffect, useLayoutEffect, useState etc. Ask a beginner how to debounce a callback - suddenly it's a hard problem.
Functions can become unmanageable since hooks have to all be called in them in the same order (note: you can make your own hook with more hooks inside to split things up)
Trading confusion around this for much more problems such as:
Infinite loops when you both read and write to a variable in a memoized hook
Stale data if you didn't list dependencies, also if you didn't then you can prevent garbage collection on any trapped references.
Getting into a dependency hell to avoid stale references (wrapping stuff in useCallback, then "tunnelling" some of the variables in with useRef etc)
Performance degradation since hooks are slower to execute and create, non-hook functions are created every render and also will break purity checks of children, even functions in hooks such as useRef (and I believe useCallback) are quietly created and discarded every render in favour of the first one created.
Testing hooks nested in a function is harder/more complex than testing class methods
Side note: Solid framework has a better implementation of hooks which don't require dependencies
TL&DR: There is no need to refactor all old components.
useState and others react hooks introduce a new way to implement your components. They can be helpful as they simplify code reusability. You can move your specific logic to a custom hook and use it in several components. Custom hooks can call useState and they don't have any possibility to damage state from other useState calls. It allows you to split component logic more wisely.
So there are 2 main profits of using useState: code reusability and code splitting.
When it's better to refactor old components?
Let's say, you have 3-4 legacy components, which make similar things, but it's complicated to reuse code. You can rewrite such components to hooks, move all common logic to custom hook and reuse this hook in all of these components.
Also, if you have any additional questions you can take a look to this https://reactjs.org/docs/hooks-intro.html article
And one important thing: PureComponent equivalent in "functional component world" is to wrap your function with React.memo
useState, this.state and PureComponent are different terms and need not be confused together. As you understand useState is a way of handling state in a functional component whereas you use this.state for a class component.
As far as PureComponent is concerned, it used to optimize renders and you can use React.memo for the same purpose for a functional component.
Also as far as refactoring is concerned, there is no need to do that since Class components will continue to exist and react community recommends you to not refactor the previous code.
I recommend for you to watch React Today and Tomorrow and 90% Cleaner React With Hooks
also, you can read Introducing Hooks
according to using pureComponent, pureComponent is similar to Component which is Class, check classes confuse both people and machines section to understand why functions are better than classes.

Resources