What is the exact purpose of react-redux - reactjs

I am trying to understand what is redux in reactjs but it is not clear for me.react working even without redux then what is the use of redux in reactjs

Redux helps you manage the states across your application much more effectively by accessing them in a commonly accessible space (a store) by all of your components.
Imagine if you had an application which had children components nested 5 or 6 layers deep, you wouldn't want to bind the state each time and pass it all the way down. Let's say each of those nested components relied on the state change, and needed a way to alter the shared state. It would be really tedious to have to bind the state and a method of accessing the state all the way down the chain. Enter redux - much easier to access and manage states.
Another side effect you'll run into as your application grows are unintended side-effects. Neither of these issues are completely eliminated by redux - but it's intended to organize code better, and in turn make it easier to debug.
If you haven't hit the limitations React has out of the box - there is no need to grab for a new tool, Redux, or otherwise. BUT here is a built-in Redux alternative native to React:
https://reactjs.org/docs/context.html

Related

When we use Redux with React, do we put all states into Redux?

I may choose to put some states as component states, and I thought that's what useState() is for.
However, the book Learning React, O'Reilly, 1st Ed, 2nd Release, p. 185, said:
With Redux, we pull state management away from React entirely.
Also, in the official Redux website, the example "Real World" also even make isFetching a Redux state, instead of component state. (Its GitHub repo).
I also found that in some project in some company, coworkers seem to favor everything as Redux state even when it can be a component state.
For example, in that same book, p. 185, it said we even keep which messages is expanded or not into the Redux store. But which message is expanded, seems entirely local to this component and it has nothing whatsoever to do with other components at all. In the case of isFetching, as least I can understand it that what if the whole app wants to unite the isFetching of any component into a global spinner indicator.
This webpage also says:
The solution in idiomatic React – i.e., code that was written the way an experienced React developer would write it – is to have what's called a single source of truth, which is one master state for most if not all of your application, then send that state down as props to your child components.
be a pragmatic programmer: go for stateless components where possible
I don't quite understand it. How does it work? When a state can be a component state, would it be perfectly ok to put it as component state? Or in React / Redux, the rule is to make everything into a Redux state? (in such case, then what is useState() for?)
Update: I like #RemcoGerlich's answer, and I put two links as a comment under his answer. Those are official docs stating "Don't put all states into Redux".
It is an eternal discussion. There are several types of state that have their own best ways to solve them:
Navigation related state, to go to different "pages" or kinds of views in your application. For this, using the browser URL has many usability advantages, and using React Router is much more natural.
State retrieved from the backend through its API, this isn't really state of your frontend at all, you have a cache. For this a library like React Query is much more suited (it handles e.g. your "isFetching" state, as well as reloading things after a while).
Small bits of state that only have local significance, like whether a small control that hides some detail is now open or closed. I feel things that are used only locally should be stored only locally, like in useState.
Often the number of things left is quite small, and putting them in one or a few Contexts is fine, except if your application becomes quite complicated.
But, Redux comes with its own advantages -- a single way to make undo functionality, a way to serialize / rehydrate its entire state, and Redux dev tools that allow looking at the action history in case you find yourself debugging complicated effects to do with the order in which happened. If you use this heavily, then you would be inclined to store more state in Redux than you would if you only make a little use of these advantages.
So it's matter of degree, it's more art than exact science, there are no strict rules. "Put everything in Redux" certainly sounds suspect to me, but who knows about your team.
If your state and operations on that state are moderate in size then react Context API is really smart enough to support you. Even, #danAbrvmov writes:
React Redux uses context internally but it doesn’t expose this fact in the public API. So you should feel much safer using context via React Redux than directly because if it changes, the burden of updating the code will be on React Redux and not you.
You may like reading his article: You Might Not Need Redux
As for, you see some companies and projects using Redux, this is because Redux is out there for a long time and Context API is newer. Moreover, if you really need some features like redux-thunk, you can still use it.
I doubt you clearly understand how the state is handled in React.
In a typical React application, data is passed top-down (parent to child) via props. You may like my answer on another post to learn when we may need Context API or Redux at all: https://stackoverflow.com/a/62980048/9857078

Global State for React

Pardon my ignorance. I am still pretty new to React. Is there anything particularly wrong with storing certain values in the state of the App component and passing a prop to child components that allows them to set the state of App? Of course I wouldn't use it to store all of the state for child components, just certain values I want available everywhere.
You can use React-context or Redux, for example, redux is a predictable state container for JavaScript apps (something like a global state, which could be accessed all over the project)
check it here https://redux.js.org/
I think you should look into redux/react-redux or recoil. These are libraries which are made to handle global state (or state which is needed in multiple places).
However if your app is very small and does not have much state it is imo fine to keep that state in the App component. Just make sure that you'll look for alternatives once you application grows as it isn't very performant or readbable to do so in bigger projects.
Redux was/is considered the go to state management library for react applications by many. It integrates great with react and is very mature. I would go for it if you expect your application to have a complex global state or become more and more complex over time. There are also great companion libraries available. For example redux-saga if you want to handle side effects or redux-persist if you want to persist you apps state.
Recoil is still pretty new and especially made for react apps. Even though it is only around for a few months you can probably expect it to develop nicely as it is backed and used by facebook. Arguably it is the more performant and easier to get into choice, but you'll probably find less guides and tutorials due to its novelty.
If you only have a few values you could also just use reacts context api.
You have two options, React-context or Redux, both of them works as you want
It is certainly right to do so in some cases, other options are using react context or react-redux
For a simple value your first option is ok, if you need to store more complicated values and need to update them frequently I'd suggest using any of the other options.
They both have some significant learning and setup curve though.
It depends how deep is your application tree. If it is a very simple app, you can get away with just using React state. If it is something more complex (like 3 or more levels deep), I suggest to use React Context (for simple values) or Redux for more complex actions.

How to pass authentication in React?

Without some global state management library like Redux, what would be a good way to pass the user around through my components? I'm using Firebase, so I'm imagining my top-level app component will be listening to auth changes and storing the user somewhere. Here are the options I've thought of:
Passing 'user' to each route in props (and on to children that need it)
Using a global object of my own
Using Context
1 seems like a hassle.
2 doesn't seem like the right way and like more of a hassle, wouldn't I have to listen for changes and set the user in my states? It's what they show in the React Router docs but I'm guessing that's just for simplicity's sake and not best practice.
3 seems like the best way to me but it seems like it's discouraged:
The vast majority of applications do not need to use context.
If you
want your application to be stable, don't use context. It is an
experimental API and it is likely to break in future releases of
React.
I would still say that you use context. It's the best way I have found to thread a common state throughout the react tree.
Even though they discourage it, all popular react libraries (including react-redux) use it big time. It's not going to be removed any time soon. And the use case seems very legit, provided you know what you are doing.

How do I use stateful components with redux?

I am trying redux right now and very excited about ideas behind it, but first real task ruined the whole thing.
In Redux we should store immutable state and produce some reducers to transform it. It means that every state could be reproduced by given previous state and a list of actions fired.
But what if I need to store third-party/legacy stateful object? For example it may be something like gallery or websocket client.
I assume that I'm able to use reducers to start/stop/manage it somehow, but the state I have no longer stateless and it not guaranteed to be repeatable with given list of reducers (websocket client may generate new session id or even be unable to maintain connection).
What is convenient way to solve these issues?
As I see this, your problem boils down to: How do you mix Redux with stateful components (legacy/third party)?
You are right, Redux is better suited for controlled components, that is, components that are mostly stateless and are supposed to receive everything as props. Just keep in mind that having some state doesn't necessarily make the component unusable in Redux. Example: For an Autocomplete component, the "open" state (whether or not the dropdown is visible) doesn't necessarily has to be controlled by Redux. So, depending on the how the component is implemented, you're definitely having a hard time integrating it into Redux, or maybe not.
You have 2 options: You either refactor the problematic components so they're now controlled, or you don't keep their state on Redux (you're not required to). The answer will vary depending on the circumstances. There's not a globally accepted solution for your case, that I know of.
Here's a nice explanation from the FAQ docs. In short:
Do I have to put all my state into Redux? Should I ever use React's setState()?
There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state.
Using local component state is fine. As a developer, it is your job to determine what kinds of state make up your application, and where each piece of state should live. Find a balance that works for you, and go with it.
There's a bunch more info there -- worth reading the whole thing.
Remember: There is no magic to redux; it's just a wrapper/container that is setting the props for you.
You can even use shouldComponentUpdate to manage how changing your stateful component's props should trigger the rendering.
Or leverging on connect's
areStatesEqual
areStatePropsEqual
areOwnPropsEqual
areMergedPropsEqual
for greater control
related: https://stackoverflow.com/questions/58027300/what-is-the-main-difference-between-using-react-redux-hooks-and-react-redux-conn#:~:text=connect%20can%20be%20used%20with,used%20with%20function%20components%20only.&text=Using%20hooks%20is%20simpler.,disposal%20in%20comparison%20with%20connect%20.

How much state does really belong in the stores?

I was wondering, how much state does really belong into the stores, and not into the components? I've read at some places that really all state should live inside the stores.
Would that include really component specific stuff, like input values (before submitting), input validation, if a modal is open, if something has been clicked etc?
What are the best practices here?
The obvious answer:
Keep component specific state (input value, modal open/ closed, stuff clicked, layout, formatting) inside the component state as much as possible.
And app specific state inside the store. Which includes, but is not limited to, stuff you send back and forth with a server.
That said, there is a lot of grey area here:
are filters applied to a search list component state? Or app state (if you save filters for future visits to the same page)?
are visited links in a global root-menu root-component state or app state?
if you are using optimistic updates, you may have a need to save user input stuff in the store, before and after communication with the server.
Some rules of thumb I use:
State belongs in component if it has the same lifecycle as the component (so if the state does not need to exist before the component mounts, and if it can be forgotten after the component unmounts)
If the state needs to be remembered when closing and reopening app, it is probably best put inside the store (where you do exchanges with server and/or localstorage)
If in doubt, start with state in component only: it keeps state much more localised (to the component) and keeps your code more manageable. At a later stage, you can always move the state to the store.
Keeping everything in flux stores may be benefitial for some apps.
So first, you should try to decide whether your app is like this.
If you're not sure whether a piece of state belongs to a flux store, then it's most likely that it doesn't.
You'll know when you need flux. And when you reach that level of understanding of whether such application architecture is appropriate for you, you'll probably know the answer to your initial question as well.
But of course it's nice to have some kind of specific guide, maybe just a mental guide, telling you when to keep state inside the component and when not to.
I'd go with these guides:
Is this state purely UI-related? Then you probably don't need to keep it in the store.
Is this state shared anywhere else outside the component? If not, then don't put it in the store. It's fine inside the component.
Can this state be persisted in the URL? If so, then don't put it in the store; put it in the url! It might be a search query of an input or a currently opened tab.
There may be exceptions to all of these, but in general I believe this to correspond well to the original ideas of a flux app.
P.S. Also I should say that there are a lot of talks saying that you should (may) keep all your UI inside an immutable state tree. That's how redux is introduced to lots of people. I think you should understand that while this is a great concept and it allows you so save/replay any user interactions, it is more often than not unnecessary and it's not what the main idea of Flux is about. And redux itself is a great flux tool that doesn't force you to keep all of the UI state in the stores.
View state specific to a component belongs in that component. App state which concerns many components belongs in a store.
It's debatable.
For example redux propose a pattern where ALL state belong in the store. Personally I think it is kind of impractical in many situations. It is very rare when I have any reason to store for example state of the button in the store.
But sometimes it can be advantageous. It is definitely easier to test when your whole app is stateless.

Resources