Im using Context API for multi store management and React-Redux with thunk for a single store management.
Should I stick to one over the other or should I use React-Redux for multiple store management over React's Context API.
I spoke with a friend who did vice-versa versus me for his company and im wondering why but never got an explanation.
Whats the best practice?
React Context API is somewhat harder to manage you can use redux instead to manage states.
react-redux is just used as a connector between react and redux.
You can do the following for best practices:
For multi store management you can go for redux.
For connecting react with redux you can go for react-redux.
For middle ware you can either go for redux-thunk or redux-saga.
I prefer redux-saga as it has more advantages over redux-thunk.
Redux was and still is very popular for large applications where you need to be able to maintain a single source of truth but pass down different parts of the store as props to various components. The advantage of this package is that it can make debugging easier and if implemented correctly is very robust.
As far as redux middleware goes, they are generally used for asynchronous integration. Thunk and Saga are two popular libraries. Context should be able to handle async without any other dependencies.
Context API is a newer feature released as part of React 16.3 and allows for easier store creation but, in my opinion, can be more difficult to scale. I don't have as much experience using Context API but it has become very popular and for an experienced developer can do anything redux does.
I would say it is generally discouraged to use both when one approach would work just as well. That being said, an application I manage uses both, because when it was first created Context API 16.3 had not yet been released so redux was the only state manager for the whole app, but later some localized component states were updated to have their own context store. I don't think this is the best practice, however.
Read more about the technical differences here.
One of the best and most overlooked alternatives to Redux is to use React's own built-in Context API.
Context API provides a different approach to tackling the data flow problem between React’s deeply nested components. Context has been around with React for quite a while, but it has changed significantly since its inception. Up to version 16.3, it was a way to handle the state data outside the React component tree. It was an experimental feature not recommended for most use cases.
Initially, the problem with legacy context was that updates to values that were passed down with context could be “blocked” if a component skipped rendering through the shouldComponentUpdate lifecycle method. Since many components relied on shouldComponentUpdate for performance optimizations, the legacy context was useless for passing down plain data.
The new version of Context API is a dependency injection mechanism that allows passing data through the component tree without having to pass props down manually at every level.
The most important thing here is that, unlike Redux, Context API is not a state management system. Instead, it’s a dependency injection mechanism where you manage a state in a React component. We get a state management system when using it with useContext and useReducer hooks.
If an application isn't overly complex, it is highly preferable to use the built-in Content API over adding another library that adds unnecessary complexity. Remember - most states do not need to be global.
A great next step to learning more is to read this article by Andy Fernandez: https://www.scalablepath.com/react/context-api-vs-redux
Related
I have seen it is becoming mandatory to use state pattern i.e mobx or rudux etc for building any react application. I am concerned that how much it is necessary to use these patterns. like if i have an application and have some pages in it each one is populating data with calling some restfull. So we can have handle it by adding some of optimization techniques like useEffect, usememo and usecalback and obviously custom hooks etc. Shouldn't it must be cleared before starting development application that how much we want to track changes in applications and how much global state we want to use. it we want only one global state ie auth status. we can use simple context and doing all with having simple techniques. So that our application become less dependent upon these libraries. If it is not like that which are the requirement that must be cleared before starting an application to decide whether to use state pattern or going with simpler version of react
It's not mandatory. In fact, my startup's codebase doesn't use any state management library. Just useState and for a few special cases we rely on useContext. React even offers useReducer (which is a simplified Redux).
I used Redux for a project and I hated it. If you're going to use it, follow the rules. Redux should be side effect free and immutable. When needing async data, you often have to use complicated middleware and other libraries (e.g. Redux-Sagas).
The good thing is that you can use a state management library for a part of your app. Maybe even another state management library for a different part.
In some cases, it might be useful to use a state management pattern. Certainly when it allows you to make some logic more understandable, readable or testable.
My take away: Always try to keep it simple
I am planning to build a large React application which might contain hundreds of components. But not sure what state management system to use between Redux and Context API.
Context API is in-built in React and doesn't need any third party library. It is easy to implement and solves the problem of sharing states at different levels of the component.
But on the other hand Redux is the Industry standard and has support for middleware to perform async actions.
If I choose Context API how can we manage API calls with it. Also do you think it is a good idea to use context for a large application where we might need state objects extensively.
The design benefit from Redux is that the action does not implement. An action is an indication that something happened (for example SAVE_PROFILE_CLICKED) but the action doesn't do anything (like connecting to api, sending data and saving response in state). You can do this with context api but the separation isn't enforced as much and you won't have the redux devtools. The pattern is called event store/sourcing. You could change the reducer and replay the events to see if your changes work and create a consistent state, testing is easier, extending is easier, logic is better isolated and probably many more benefits to be had.
The design also separates writing to state (reducer), side effects (thunk) and reading from it (selectors). This pattern (writing/reading separation) is called cqrs. Your query/selector is separated from the command/reducer. This gives you easier testing, isolation of logic, less chance of duplicate implementation and probably many more benefits.
You can still make a complete mess of your project when using Redux and not fully understand it so using Redux does not guarantee anything.
If I choose Context API how can we manage API calls with it.
You can do it any way you like it, the question is too general to answer.
Also do you think it is a good idea to use context for a large application where we might need state objects extensively.
As stated before; Redux is no guarantee your project won't be a mess. It will give you the tools to implement certain patterns with more ease. Make sure you understand it and it's patterns. Most example applications don't demonstrate why Redux is so powerful as the problem they implement (counter, todo app) isn't complex enough to even warrant using it. I can only advice you would write code that you're comfortable with and can understand.
I am using Apollo Client 3.0 to fetch data from graphql server, but I can't decide what to use for local state management (Redux or Apollo Client 3.0).
I think Redux force me to write more code, but in a predictable and cleaner way which it's good. Also adding Redux to the app means I will have mix of 2 state management libraries.
Apollo Client 3.0 has Reactive Variables, but for large application I think it will become a mess! Also I can use queries and mutations with #client directive, but this could be a little bit confusing.
What do you recommend me ?
What should I use ?
Can you provide me some good examples ?
Thanks!
Apollo is not a state management library. It's an amazing client & cache for graphql, but when you start using it as a client-side state management, you'll notice that it isn't really meant for that.
The amount of code you have to write is similar to vanilla redux, as you have to write your own resolvers for every local query and mutation, but since there is a text-based protocol in-between, you lose all type safety you could have when staying "pure JavaScript". And then you have to manually put your data into a normalized cache, even if your data is not normalized, so you'll start putting your settings into settings/1, because everything needs an id, even if you have only one instance of settings in your application.
It all feels very clumsy from my experience.
Also, modern redux has a lot less boilerplate than you might be used to right now - if you follow the official recommendation to use redux toolkit (take a look at this page of the official redux docs), you'll write probably a fourth of code code you are used to with "vanilla redux".
Modern redux doesn't have hand-written action creators, action types, switch-case reducers or immutable logic. Those are all implementation details that are handled under the hood by now.
I actually did a conference talk on the topic a year and half ago, so I have some examples.
Here is what you write with Apollo (and yeah, the example is a bit artificial for Apollo - but I wanted to use the same example for all libraries and a login flow was what I had gone for)
This is what it looks like in redux
I’m wondering why people doesn’t seem to use GraphQL jus with Redux.
I’ve never used GraphQL before but I’d like to start a new project, but neither Apollo and Relay doesn’t convince me. Currently I’m creating an app that use react and redux and “old fashion” rest api. And I love the idea of redux that it store whole informations about my app in one place.
And now, as far as I understand both Apollo and relay does something similar but they use separate store and in both we mixing the logic and view even more than with just React, both of these things (another store and mixing code) seems to be a bit messy. The advantage is caching, am I right?
So why can’t we just send the query as we used to with normal rest api and put the data to the redux store (maybe try to store some kind information about sync for optimisation).
Sorry if there are thing that i missed, I’m new here and I’m not a pro, it’s why I ask some people that probably has more experience that me :)
"store some kind [of] information about sync for optimisation" becomes a very hard problem when you have lot of interdependent entities.
Also, structuring the client side state is a hard problem in large applications. The rules of thumb, considered as best practices, in the redux community are that you need to normalize and remove redundancy in your redux state tree when inserting and denormalize them when using in components.
The libraries like relay and apollo want to own the state they manage so that they can remove this responsibility of normalizing/denormalizing the data, and managing the cache (as much as possible) to a significant extent from end users while still providing them low level control when they need to.
This is a fairly sophisticated problem because different components may depend on partial models eg. NoteSummary component may need only title and tags fields, the NoteDetails component will need description and comments too.
If you manage the redux state yourself you will have to write code for the following, when NoteDetails component is presented:
If a Note is not already present in the redux tree, fetch the required fields using a graphql query.
If a Note is already present, but not all the required fields are present, create a graphql query for the missing fields, and then fetch them by querying the graphql server.
If a Note is already present, and has all the required fields, just use the local version.
This becomes a lot more complex when we have entities which have dependencies on each other, or when realtime collaboration or subscriptions are involved.
GraphQL libraries attempt to solve all of the above in a very network efficient manner. Using react-apollo or relay your component can declare what all it needs and the underlying library, will intelligently figure out what and how much to fetch.
This is philosophically similar to how you write react components: In your render method you declare what your final component hierarchy should look like (given present state) and the library (react) figures out what changes are to be made to the DOM.
You should evaluate if your use case benefits from this kind of network efficiency and if so, whether you are willing to invest time putting in the effort required to learn GraphQL and the ecosystem around it.
If a redux store and a few ajax calls suffice for your use case, it can be a much simpler setup.
If you decide to go full on with GraphQL and Apollo, you might want to not have redux at all. You can use apollo-link-state and manage all your data (local or remote) using graphql Queries and mutations. Then from the perspective of your components it becomes irrelevant whether some data is remote or local.
Having said all the above, if you really want to just use redux along with graphql without any additional libraries like Relay you can use Apollo client directly. You can dispatch thunks from components, then in your thunks, you can make graphql queries directly using the Apollo client, and once you receive the response you can put that data in the tree in the tree using another action dispatch.
If this sounds more complex, it is because it simply is.
Are Relay and Redux alternatives to each other? When are they best used with? Can we use Relay, GraphQL with Redux?
REDUX:
Redux is library
Redux is a state container for your app
Its a single point source where all information related to your app is stored.
You create actions,reducers and update your state by dispatching actions.
The state is immutable and you cannot update it. Always a cloned version of state is returned.
You use packages like redux-thunk / redux-saga to call apis. On Response of API's you update your state.
Now if you see in redux there is a lot of boilerplate code.
I personally find redux really cool and handy but you need to take care of following:-
Creating actions/reducers/store.
Dispatching actions and updating store.
Handling api calls.
Implement caching.
Maintaining store.
Maintaining expected props in components.
RELAY:
Relay is a Javascript Framework.
Handles store for you. You dont have to worry about updating store
Takes care of your API calls(this is the best feature)
Store is immutable and clone version is returned.
Works with GraphQL(this part is bit tricky as you need to understand graphql as well). After working on this for sometime I realised this is one major drawback. But once you understand graphql its really powerful
Works on queries and mutations
Relay is really really powerful and provides following benefits:-
You dont need to work about API calls. Relay network layer takes care of it. You do that through specifying queries and mutations
One of the best features of relay which makes it really useful is caching implementation. It reduces api calls drastically.
Relay is really really powerful but you there is bit of overhead when you get started. Following are the pre-requisites:-
React
Graphql
ES2015 JS
Once you are done with prerequisites also understanding how relay actually works is bit tricky and not as easy as redux. But once you understand how it works and why was it brought into picture you would really be amazed. Its indeed a really powerful tool.
So in case of your project is small-medium sized I would say go with redux and if its on large scale relay. But if you are working on react-native do give relay a try , its really interesting.
Also,yes you can use redux with relay.