Redux vs Context API and useReducer hook - reactjs

I have been working in React for past 6 months and do not have any experience with Redux yet. Though I have worked with context api and useReducer hook. I need to convert an existing application to react which will have around 100-120 components. My question is about the choice of state management. With the rise of context api and useReducer hook, Can I rely on these two only Or Redux library is still a better choice ? Articles that I found for comparison are from late 2019 so I couldn't decide.
Please guide

Redux is still a much better choice for large scale.
Let's assume you have 10000 global state variables in the global store. And you need to change one.
Context API
It will rerender all of its consumer components which is unnecessary.
Redux
It allows us to selectively rerender components that subscribed to changed values.
So
Context API is good for small scale but not good for large scale.
Fundamentals are still same for context API before and after useReducer.

I think useReducer and contextAPI should be good enough even for large applications if you don't want the time travel that Redux provides out of box, as a by-product of its design.
For large applications, one could have a large state (or multiple reducers combined via combiner) in Redux, and yet avoid re-rendering of components. This is because components are rendered based on parts of state that it depends upon, using the mapStateToProps and mapDispatchToProps magic. With contextAPI and useReducer one designs global state by breaking it up into Providers such that only the sub-tree affected by a particular sub-part of global state is passed that part of global state via its own provider.
Check this out: https://kentcdodds.com/blog/application-state-management-with-react

Related

Redux and React context together

I am building a web app where redux is configured and app is fairly large.
Now I want to store some user preferences which will be available as part of an API respopse.
As this data is required to the majority of components I am planning to store data in the context and wrap application using the context.
I have Few questions regarding approach.
Will considering context impact the performance?
As Redux is already configured which internally uses the Context. So should we continue to use redux for user data.
Is it good practice to use Redux and Context together.
Context and Redux are very different tools that solve different problems, with some overlap.
Context is not a "state management" tool. It's a Dependency Injection mechanism, whose only purpose is to make a single value accessible to a nested tree of React components. It's up to you to decide what that value is, and how it's created. Typically, that's done using data from React component state, ie, useState and useReducer. So, you're actually doing all the "state management" yourself - Context just gives you a way to pass it down the tree.
Redux is a library and a pattern for separating your state update logic from the rest of your app, and making it easy to trace when/where/why/how your state has changed. It also gives your whole app the ability to access any piece of state in any component.
In addition, there are some distinct differences between how Context and (React-)Redux pass along updates. Context has some major perf limitations - in particular, any component that consumes a context will be forced to re-render, even if it only cares about part of the context value.
So, yes, you can use them both in the same app, in the same way you can use a hammer and a screwdriver together on the same construction job.
For more details, see my posts:
Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux)
React, Redux, and Context Behavior
A (Mostly) Complete Guide to React Rendering Behavior
Will considering context impact the performance?
Since you want to share user preferences that (I guess) do not change often, you could use a React context to share that data.
But performance issues arise when you put multiple different data in one React context that update at different rates. This is because every component that uses the context will be rerendered even if the part of the context it is interessted in did not change. In this case you can split the context and use one context for each part of the data.
Since you want to use the context to share an application state, you should use Redux. In Redux you use selectors to select a part of the application state. This useSelector hook is implemented in a way that it only triggers a rerender of the component if the selected part changes. You can even pass it an equality function if you want to change the way state change is detected.
As Redux is already configured which internally uses the Context. So should we continue to use redux for user data.
I would say: yes, continue with Redux.
Since you already use Redux you should not spread your application state management over different concepts. Put the user settings in the Redux store (like any other application state) and don't handle them special.
Is it good practice to use Redux and Context together
Well, Redux is based on the React context. So if you use Redux it is already a good practice.
If you mean using both for application state management, I think you should go the Redux or the React context way. Mixing them makes it harder to understand where state is managed.

Is a React Context basically a mini redux store?

No practical purpose to this question, just tryna connect concepts to get my head around switching from Redux to using useReducer and React contexts - is a Context when used with useReducer` basically a redux store that's only available to components that explicitly import it?
No. Context and Redux are very different tools that solve very different problems.
Context is simply a mechanism to make a single value accessible to a portion of your component tree. It's up to you to write the code that determines what that value is and how it gets updated. This is typically done by storing data in React component state, and creating a value that is passed to a <MyContext.Provider>.
Redux is a separate UI-agnostic state management library that is designed to help you write predictable state update logic and track when, where, why, and how your state has updated over time, with the React-Redux UI bindings layer allowing your React components to interact with that Redux store.
Now, yes, useReducer+useContext do have some similarities to Redux in terms of how your component will interact with them, but they also have very different performance characteristics in terms of when and why your components will re-render.
Please see my extensive post on A (Mostly) Complete Guide to React Rendering Behavior and my additional posts Redux - Not Dead Yet! and React, Redux, and Context Behavior for details on how Redux and Context differ and how
It is not hard to implement the exact logic of react-redux by means of useContext, useReducer and maybe useSelector)
But useContext + useReducer is not a full replacement of Redux.
useReducer is just an alternative to useState.
And useContext comes with https://en.reactjs.org/docs/context.html#caveats
To store multiple values you have to https://en.reactjs.org/docs/context.html#consuming-multiple-contexts

State Management in React

Which technique is better for state management in react app?
Actually I want to create a big app where I've to manage my state which technique is optimal for state management context, Redux or react custom hook?
I am personally more inclined towards Redux. But if you are a beginner trying to learn Redux you might have some hard time until you understand it. Once you get it you will also like it. Rather than building your own custom hook, It's better to use Redux as if anything goes wrong/you are struck with something, you have community to support and You can also dispatch async calls using some middleware libs like redux-thunk, etc. You can use Redux with forms as well. I guess if you end building your custom hooks you might end up wasting time, taking care of all these.
Of course, it is better to go ahead with Redux, because it is easier to handle large applications with Redux. It has only a single store, which is basically a javascript object. You can divide the store into many pieces, each piece will be for a particular part of the application. All these pieces will be joined together using the combineReducers function provided by redux.
React is a state management library and with the release of React hooks and massive improvements to React context this method of state management has been drastically simplified.
I think in 99% of the situations we do not need redux and add one layer of complexity to project.
For big scale app maybe redux is better choice. but if you choose React for state management you need good information about some concepts and this concepts is:
Local state vs global state(some component needs local state and putting all of their state in global state leads to a lot of problems)
react context and prop drilling problem and How to use React Context effectively
react hooks especially useReducer and useContext
immutable state
You would always need to ask yourself the question: Do i need an additional library?
Redux is on its decline in popularity, due to improvements on Reacts native state management. There is a reason for that!
If you want to work for a company thats not brand new, there is a chance you have to use redux. I was fortunate enough to convince my team to use our own state management library build only with React.useState under the hood.
If your application state logic is quite simple, meaning: states are mostly local, shared state are mostly between parent-child relationship and different states are not heavily depending on each other, then I recommend only using React useState and useReducer (in case you like to use reducers).
Once your application state is getting complicated, you need to have some sort extra stuff of global state management.
The most important thing you need to know about React.useState is, that the returned setState function is your connection to that components state. Lets assume we can take that function out of the component and use it somewhere else. This way you have a function to update your state from outside of your component.
export let exportedStateSetter;
const Component = () => {
const [state, setState] = useState();
useEffect(() => {
exportedStateSetter = setState;
return () => exportedStateSetter = undefined;
});
return <div>{state}</div>
};
In the example above, you can now import the exportedStateSetter and use it somewhere else to update the state of this Component.
!This is not a best pracitce example, this is a simple visualization.
When you think very critically about this, you will realize that now you know how to set a components state from outside of a component, you know how to set states globally.
I stringly recommend using this approach to either build your own global state library or use some that i have created based on what i explained:
npm install --save react-global-state-hook // simple
npm install --save rx-global // complex
To wrap it up: Dont use Redux, if not required by a job. You can always use Redux conventions, by seperating state into stores, update state with a reducer and actions that interact with the state. For that you can use native React state management, if not only React.useState when used properly. React provides you with everything you need and everything you need to build yourself.
I had the best developer experiences with my own libraries that evolved over time. It forces you to understand state management in general and the framework you are using.
Im open for any feedback on the 2 libraries and if you have any questions regarding state, please feel free to keep posting.

React 16.7 has State Hook,so I do not need react-redux anymore,is that right?

React 16.7 has State Hook,so I do not need react-redux anymore,is that right?
To my understanding so far, Hook API is still not fully compatible with redux, and supporting for redux is under development. There is a thread in Github for the implementation of useRedux method.
Meanwhile, I think react-redux is still a better choice at the moment, since its API is already optimised for React app's performance. Implementing your own comparing function for re-rendering logic based on updates of redux store's data is too much for small & medium size projects.
For global state still the react-redux is recommended way.
Use react-redux for disconnected components where need to access share state(global state).
Use react state for form-like components(local state)

React components with shared state that are far away

I am new to React so please excuse me if this is a noob question but I really could not find the answer in the DOCs or elsewhere.
Let's say I have two buttons with a counter that share the state but are far away from each other in terms of the placement in the UI.
The documentation says the common owner component for both buttons should own the state. It makes sense if the components are next to each other like in the example but what if my buttons are each part of a different UI group and are far away in terms of nesting? My state holder would be the root of the document and I would have to pass a handler function down through many layers. And what if I need to add new component somewhere else that also needs to know the state? Would I have to modify all the parent components in the way to pass the state down? That is tremendously impractical.
Without React I would have some global Subscribe/Publish pattern like jQuery Observer and all UI elements could subscribe/publish to it regardless of their nesting position.
How does React solve this?
Related question: If I need to load/save the state to DB, how do I pass a reference of the controller (or Whatever) to each React component that stores the state?
1 for global state you may use REDUX
Redux is a predictable state container for JavaScript apps
for connect/subscribe component with that state ,you should use react-redux
If components are far away in terms of nesting, you may connect/subscribe them to redux store, and take only neccessary part of state. They will update if only neccessary part is changed.
article that explains how you can do your case
to learn how to use redux you can watch this videos from creator of redux (Dan Abramov)
1.getting-started-with-redux
2.building-react-applications-with-idiomatic-redux
3.I definitely recommend to you discordapp rectiflux channel. because you allways can ask any question online.(there you can find contributors of that tools)
2 alternative way that less verbose then redux is MobX
MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming (TFRP). The philosophy behind MobX is very simple:
Anything that can be derived from the application state, should be derived. Automatically.
I suggest to look at the Flux stores. In short, stores are like model in your application. You can listen to change (subscribe) and also modify their properties (publish). You can see how it was done in example app.
A better option is to go with Redux.
Redux is enabling use cases like yours in a way simpler fashion :)
It will help you with all the state and make your life much easier.
Some good resources for learning:
The Redux Website
Video courses from Dan Abramov, the creator [Free]
Awesome course on Udemy [Not free]
Building Applications with React and Redux in ES6
And finally take a look at this youtube series [Free]
Managing state in the middle layers of your app should be avoided where possible. This data belongs in a store, which holds the global state of the app. Then each component accesses the state via its props.
The naïve approach to get the data down to the component is to pass the store through all the layers of your app "manually", i.e. through props.
Smarter alternatives exist, which use connected components, that access the global state through the context (as opposed to the props). Typically, the presentational component (your button component) is wrapped in a container component that handles this connection to the store, then passes the data in via props.
There are numerous frameworks that facilitate this process, links to which are already provided in the other answers.
If you are trying to share simple states, try this ( I am the author): react-provide-state
Otherwise I will recommend Redux. It has become the most popular tool for managing application states.
In the applications being working on, we use Redux to manage the main application states and almost all other states. But we use 'react-provide-state' for simple, UI only states like Modal, Checkbox states.

Resources