Global State for React - reactjs

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.

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

MobX with React best practice with observer

I'm not really facing an issue, it's more like I'm wondering what is the best way I should use mobx with react. So here's my situation:
I'am fairly new to mobx but I've got years of experience using react (mostly with redux).
My new project is using mobx-state-tree alongside with mobx-react-lite in order to connect my components with the function observer wrapping the component. I've set up a root store with multiples stores in it.
I'm really enthusiastic about it for now but I would like some recommendations:
Should I use the containers logic which is pretty common with redux, which means I should only connect a "container" component who will handle the connection with my stores and spread it to its children ? Or should I connect directly with an observer as many components which needs to be provided with data from a store ?
Is the second option more optimized, technically speaking ? Is it still a good idea according to React philosophy ? What's YOUR opinion on this subject ?
Any answer would be really appreciated
Technically, you don't need container/presentation concept. You can use context, or localStore, or globalStore but it doesn't mean container/presentation not useful sometimes.
Mobx patches shouldComponentUpdate lifecycle, and basically optimizes components rendering for you.
mobx-react mentioned in their docs that the more components connected with observer, the better.
It's very common pattern to see shouldComponentUpdate with a bulky checks to avoid unnecessary renders. This isn't needed with MobX at all.
My opinion is that patterns change on monthly basis, so learning the general concepts can ease your transition from global store, local store, context, hooks and other api changes.
React component patterns also change overtime.
Use what you need and understand right now. If it won't matter in 5 years, don't spend more than 5 minutes to think about it. You can always do a fun refactor.
Further reading:
https://mobx.js.org/README.html
https://mobx-react.js.org

What is the exact purpose of react-redux

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

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.

Om but in javascript

I'm getting to be a fan of David Nolen's Om library.
I want to build a not-too-big web app in our team, but I cannot really convince my teammates to switch to ClojureScript.
Is there a way I can use the principles used in om but building the app in JavaScript?
I'm thinking something like:
immutable-js or mori for immutable data structures
js-csp for CSP
just a normal javascript object for the app-state atom
immutable-js for cursors
something for keeping track of the app-state and sending notification base on cursors
I'm struggling with number 5 above.
Has anybody ventured into this territory or has any suggestions? Maybe someone has tried building a react.js app using immutable-js?
Edit July 2015: currently the most promising framework based on immutability is Redux! take a look! It does not use cursors like Om (neither Om Next does not use cursors).
Cursors are not really scalable, despite using CQRS principles described below, it still creates too much boilerplate in components, that is hard to maintain, and add friction when you want to move components around in an existing app.
Also, it's not clear for many devs on when to use and not use cursors, and I see devs using cursors in place they should not be used, making the components less reusable that components taking simple props.
Redux uses connect(), and clearly explains when to use it (container components), and when not to (stateless/reusable components). It solves the boilerplate problem of passing down cursors down the tree, and performs greatly without too much compromises.
I've written about drawbacks of not using connect() here
Despite not using cursors anymore, most parts of my answer remains valid IMHO
I have done it myself in our startup internal framework atom-react
Some alternatives in JS are Morearty, React-cursors, Omniscient or Baobab
At that time there was no immutable-js yet and I didn't do the migration, still using plain JS objects (frozen).
I don't think using a persistent data structures lib is really required unless you have very large lists that you modify/copy often. You could use these projects when you notice performance problems as an optimization but it does not seem to be required to implement the Om's concepts to leverage shouldComponentUpdate. One thing that can be interesting is the part of immutable-js about batching mutations. But anyway I still think it's optimization and is not a core prerequisite to have very decent performances with React using Om's concepts.
You can find our opensource code here:
It has the concept of a Clojurescript Atom which is a swappable reference to an immutable object (frozen with DeepFreeze). It also has the concept of transaction, in case you want multiple parts of the state to be updated atomically. And you can listen to the Atom changes (end of transaction) to trigger the React rendering.
It has the concept of cursor, like in Om (like a functional lens). It permits for components to be able to render the state, but also modify it easily. This is handy for forms as you can link to cursors directly for 2-way data binding:
<input type="text" valueLink={this.linkCursor(myCursor)}/>
It has the concept of pure render, optimized out of the box, like in Om
Differences with Om:
No local state (this.setState(o) forbidden)
In Atom-React components, you can't have a local component state. All the state is stored outside of React. Unless you have integration needs of existing Js libraries (you can still use regular React classes), you store all the state in the Atom (even for async/loading values) and the whole app rerenders itself from the main React component. React is then just a templating engine, very efficient, that transform a JSON state into DOM. I find this very handy because I can log the current Atom state on every render, and then debugging the rendering code is so easy. Thanks to out of the box shouldComponentUpdate it is fast enough, that I can even rerender the full app whenever a user press a new keyboard key on a text input, or hover a button with a mouse. Even on a mobile phone!
Opinionated way to manage state (inspired by CQRS/EventSourcing and Flux)
Atom-React have a very opinionated way to manage the state inspired by Flux and CQRS. Once you have all your state outside of React, and you have an efficient way to transform that JSON state to DOM, you will find out that the remaining difficulty is to manage your JSON state.
Some of these difficulties encountered are:
How to handle asynchronous values
How to handle visual effects requiring DOM changes (mouse hover or focus for exemple)
How to organise your state so that it scales on a large team
Where to fire the ajax requests.
So I end up with the notion of Store, inspired by the Facebook Flux architecture.
The point is that I really dislike the fact that a Flux store can actually depend on another, requiring to orchestrate actions through a complex dispatcher. And you end up having to understand the state of multiple stores to be able to render them.
In Atom-React, the Store is just a "reserved namespace" inside the state hold by the Atom.
So I prefer all stores to be updated from an event stream of what happened in the application. Each store is independant, and does not access the data of other stores (exactly like in a CQRS architecture, where components receive exactly the same events, are hosted in different machines, and manage their own state like they want to). This makes it easier to maintain as when you are developping a new component you just have to understand only the state of one store. This somehow leads to data duplication because now multiple stores may have to keep the same data in some cases (for exemple, on a SPA, it is probable you want the current user id in many places of your app). But if 2 stores put the same object in their state (coming from an event) this actually does not consume any additional data as this is still 1 object, referenced twice in the 2 different stores.
To understand the reasons behind this choice, you can read blog posts of CQRS leader Udi Dahan,The Fallacy Of ReUse and others about Autonomous Components.
So, a store is just a piece of code that receive events and updates its namespaced state in the Atom.
This moves the complexity of state management to another layer. Now the hardest is to define with precision which are your application events.
Note that this project is still very unstable and undocumented/not well tested. But we already use it here with great success. If you want to discuss about it or contribute, you can reach me on IRC: Sebastien-L in #reactjs.
This is what it feels to develop a SPA with this framework. Everytime it is rendered, with debug mode, you have:
The time it took to transform the JSON to Virtual DOM and apply it to the real DOM.
The state logged to help you debug your app
Wasted time thanks to React.addons.Perf
A path diff compared to previous state to easily know what has changed
Check this screenshot:
Some advantages that this kind of framework can bring that I have not explored so much yet:
You really have undo/redo built in (this worked out of the box in my real production app, not just a TodoMVC). However IMHO most of actions in many apps are actually producing side effects on a server, so it does not always make sens to reverse the UI to a previous state, as the previous state would be stale
You can record state snapshots, and load them in another browser. CircleCI has shown this in action on this video
You can record "videos" of user sessions in JSON format, send them to your backend server for debug or replay the video. You can live stream a user session to another browser for user assistance (or spying to check live UX behavior of your users). Sending states can be quite expensive but probably formats like Avro can help. Or if your app event stream is serializable you can simply stream those events. I already implemented that easily in the framework and it works in my production app (just for fun, it does not transmit anything to the backend yet)
Time traveling debugging ca be made possible like in ELM
I've made a video of the "record user session in JSON" feature for those interested.
You can have Om like app state without yet another React wrapper and with pure Flux - check it here https://github.com/steida/este That's my very complete React starter kit.

Resources