apollo benefits vs. redux with selectors - reactjs

our team is using a hybrid of redux/sagas/apollo.
my question: why even use apollo to wrap components if we can
call fetch on the graphql endpoint
update our Redux store
use selectors to memoize and cache results
is there any other benefit besides code readability? (tying Apollo's graphql higher order component to the view)

Couple of things here. You can do what you described. In the end you can merge concepts together at your own will. There is no central authority deciding that you must keep concepts separate or together.
The question is really a team decision regarding how you collectively feel about redux's syntax and tradeoffs versus that of other state management. When you take that and compare it against your immediate needs then you ultimately must decide what the cost / benefit is.
Does your team feel ok about just using setState, bringing in unstated only when needed? Do you move away from higher order components since Apollo supports render props which are more easily composed? Might you be better off just using Apollo instead of redux? Do you want to use Apollo for your remaining local state?
Naturally I am leading you to my opinions based on what the community is exploring at the moment. Should you rewrite your application to use a certain pattern? Only you and your team can evaluate your current pain points you are running into to determine that. As long as you continue to ask questions like this an attempt to compare it against your team's needs then you'll be on the right track.
Redux works great in apps, but many teams run into challenges when they seek to generalize components that rely on redux, favoring more composable state solutions. Naturally YMMV.

Related

Statecharts for Redux

Current State Management Stack: React, RTK/Redux, and Redux-Saga
Here's the high level issue. We have a complex flow and we don't have QA Engineering resources to be able to write the integration tests needed for this. This leads to the following issues:
A lot of context needed to change something in this flow(without introducing bugs)
Having to manually test a lot of different paths in the flow to try and make sure nothing was broken
A huge lack of efficiency
Even with dedicated QA effort, bugs still slip through to production with how many paths there are
I've been looking at xstate and really love the ability to generate statecharts(less context needed, non-technical stakeholder understanding, & seems like it would result in better efficiency moving forward). For state management, we currently use Redux across the platform(changing this would be incredibly out of scope). This leads me to my questions:
Does anyone know of a (well supported)npm package where I can integrate Redux with statecharts?
If not, what are the pros/cons of implementing both xstate and Redux? Xstate would only be for this flow and would need to pull some data from Redux. While Redux state is available to xstate, I'm assuming I wouldn't need to write it in a way that Redux is dependent on xstate.
I'm not super familiar with xstate but I don't want to dive too deep if this ends up being a waste of time/terrible idea.
ALSO - for context, this is a very large repo & the solution needs to be maintainable, readable, and most importantly - scalable
ALSO 2 - The main goal of this is the auto-generated statecharts. We have many hands in this flow and keeping documentation up to date manually is not feasible
You can always use statecharts as Redux reducer functions! In fact, one of the XState devs put together an example repo demonstrating exactly how to do that (as well as using XState services in a Redux middleware for side effects):
https://github.com/mattpocock/redux-xstate-poc

Is React Context API suitable for large scale applications

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.

Best practices for managing state and props in larger React apps

I would like to understand more about the best practices for passing props around parents-child in react. the problem comes from having a standard way of doing this in a medium-large project to minimize confusion and technical debts such as performance optimization. So far, I only knew these methods on doing this:
standard prop drilling
Pros: easy
Cons: will become unmanageable in complex feature
utilizing React.Context
Pros: medium difficulty, naturally separate from main component
Cons: more time to write, may be unnecessary for smaller components, will do re renders that will cause performance issues headaches in, for example, large forms.
using global state from 'reactn' module
Pros: easy
Cons: will get unmanageable for large projects that have tons of components, cannot prevent rerender AFAIK.
using Redux
Pros: robust and compatible with firebase (react-redux-firebase, redux-firestore), can prevent rerender using areStatesEqual,
Cons: more boilerplates, more work to do for simpler state management
is there a guideline on standard practices on doing this? what do you people use for medium-larger projects? thanks!
The following answer is subjective!
There are basically 3 categories that I am aware of.
Keep everything local ( For any size of app which doesn't deal with sibling dependencies this will work fine. May cause some prop drilling, though it should be avoided as possible, it's not an anti-pattern. You come with better approaches to handle this i.e. PureComponent, React.memo, shouldComponentUpdate)
Keep everything global(redux/reactN/...) (have not seen this approach in my experience, not recommended in my opinion as requires you to hit central state every time when there is a change)
Keep a mix of both. (Highly seen this in medium to large scale projects, we use this approach with redux)
Choosing an option:
Personally speaking, irrespective of the size of an application one can start with the first approach and add the central state later when required(if you are not sure where to put states).
If you need to manage some state centrally from the beginning it can be added from start(if states are clearly defined).
If you choose any one of the above two approaches, to begin with, at one point in time you would need to decide either go for first-party i.e. React Context or a third party i.e. Redux, ....
You have already stated the pros and cons of these, you can compare and see which one outweighs the others.
For a simple answer from the list you provided I would suggest redux, writing actions and reducers does add a certain amount of overhead, and as react evolved and matured it now seems you can manage large applications w/o the use of redux: https://medium.com/#dan_abramov/you-might-not-need-redux-be46360cf367. But once you get how redux works you will be able to scale with ease. This is a good solution for react-redux beginner-intermediate level devs.
The best suggestion I have for you is to use react only.
useContext and useReducer will get you very far, but it requires an intermediate - experienced development skills. This approach will force you to invest time in data-structure, encapsulation of components and use of advance react patterns. (I would enroll to something like https://kentcdodds.com/workshops/advanced-react-patterns)

Why can’t we use GraphQL just with 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.

Is there a way to deveop by each module with react, redux, side effect

I'm developing Web project with react.
But bigger code size the speed is slower. And All code in one system is easy to be complicated and hard to maintain
Is there a way develop by each component with redux, side effect all in one module?
For example, modulizing one component(comtainer) with is's action, stores, side effect. And attach main code with build system..
At the end of the day, a single store will contain all state in redux. The exception to this, is if you choose to run two seperate apps on the same page - but they wouldn't be linked in any way whatsoever (so ignore it).
However, you can use combine reducers to join reducers from multiple components into one store while keeping them separate. For the majority of apps this will suffice completely, and I would find it hard to imagine it would cause performance issues unless it is set up incorrectly.
Your question doesn't lend itself to one concrete answer, but rather patterns. I would look into "ducks" for redux - its not a technology or library, but rather a pattern for keeping your stores and components modular.
Ducks: https://github.com/erikras/ducks-modular-redux
Explanation: https://medium.com/#scbarrus/the-ducks-file-structure-for-redux-d63c41b7035c#.36dsdqd5q
Personal favourite structure doc: https://hashnode.com/post/tips-for-a-better-redux-architecture-lessons-for-enterprise-scale-civrlqhuy0keqc6539boivk2f
If you still feel like redux doesn't align to your modular app, you can consider not using it - sometimes there is no need for it. https://medium.com/#dan_abramov/you-might-not-need-redux-be46360cf367#.p7j6cioou

Resources