React- Apollo Client- structuring components - reactjs

Let's say component - TodoList need to show the list of TODO's in 2 different ways, listview and gridview .there is a switch on the page that toggles between the views. Assuming I want to keep the 2 views as different components, what is the best practice -
create TodoList component with graphql query and then pass the result of the query to TODOListView and TODOGridView components?
create TodoList component with NO graphql query and then write the same grqphql query inTODOListView and TODOGridView components (not DRY, query duplication in each component, but apollo cache will make sure that it is not called multiple times)?
good/bad with each approach?

IMHO there is no real choice, cache usage has no value as argument then no good parts with second approach.
Taking usability, UX, user centric design you probably want to keep page, sorting and filtering state while switching type of view. As an user you're expecting this kind of behaviour. This is easily available only with first solution.
Assuming I want to keep the 2 views as different components
IMHO this is wrong assumption, too. Of course you can do that but Lists are almost the same, the real difference is in item/row rendering. If this is a simple styling sets change (or adding a few elements) then even no need for using components for items, just conditional rendering. You can change/refactor it later.
Utilizing item components you can have additional abstraction layer and more complex use cases available. With passed down (into items) switching type handler I was able to change it (gloablly) from simgle item level or change locally item view type - mixed element list.

Related

React: How to pass data and methods to hierarchically organized components

i have a page with components distributed by layers as follow:
I have a main page that contains several components and which in turn contains other components. Each level of the parent-child hierarchy I call a layer.
I separate these components into 3 types, reusable, coupled and modal:
Reusable - Receive data by props and do what they need to. They can be reused in any context (page) because they are not coupled.
Coupled - They are bound to the context (page) and can receive data by props or fetch data via API request.
Modal - It is the last layer of the layers, however they are decoupled and receive the data and methods of the actions they need to perform.
The flow I run today is to get the main data when entering the page, then I pass the data via props to the respective components, as the user accesses it.
In some cases, due to the amount or sensitivity of the data, I request more data inside the coupled component, when the client accesses a higher level of detail.
And finally, I pass the data and methods to be executed in the last layer (modal components). There are scenarios where the method is created on the 1st layer (page) and only executed on the last layer (modal).
Based on this context above, what would be the most efficient way to pass data and methods to components?
Currently I pass via props, however, I still have doubts if this would be the best way or using ContextAPI.
I agree with you #kanuos !
After many time thinking about it, I'm using 3 options.
But which one do I choose? As #kanuos sad, depends!!
These are the 3 options I have and use:
Continue using Props Drilling - Some cases is necessary.
Use Context - It works well to avoid a lot of prop drilling.
Composition - Sometimes I want to avoid a lot of prop drilling and I also don't want to maintain a context dependency. In this case using the composition pattern I can directly pass the
properties to what I want.

How to structure Redux for a highly de-coupled, plug-n-play complex component?

I'm pretty new to Redux and would like to use it my application but I'm stuck at architecture/design phase for the Redux part. Here are my requirements and my suppositions regarding the design.
Application details:
SPA with AngularJS. Other libs used ng-redux, reselect, rxjs.
Component details:
Re-usable grid component to render huge amounts of data.
My idea:
Create a plug-n-play kind of component-based architecture, where all the internal components of the grid are independent of the parent/composing component like search, sort, row, header, cell.
All the components will have their own set of reducer, action, selector, and slice of state from the store.
Because all the components have their own reducers and can be plugged-in on demand, I need them to be lazily registered to the store instead of being accumulated in one place.
Some of the components like search, sort along with having their own state, also can affect other components state. Ex: setting up of query parameters (searchText, sortOrder etc.) to fetch the grid data which would be handled by another component(s).
My thoughts:
For the 1st point, I'm looking into reselect for supplying the dependent slice of state.
For the 2nd point, I'm still confused about which to use combineReducers/replaceReducer for the lazy registration. I feel combineReducers will not fit if I want access to multiple parts of the state.
For the 3rd point, I'm thinking of following approaches:
a. Passing entire state via getState() wherever required to update multiple parts of the state. Though this approach gives me feeling of improper use of Redux.
b. Component A fires its own action which updates their part of the state, then another action is fired for the other component B to update its slice of state. This approach as well feels like breaking the whole idea of Redux, the concept of side-effect could be used here though I don't know how to use it, maybe redux-saga, redux-thunk etc.
NOTE: Use of either of the approaches shouldn't lead to the component knowing about the other components hence whatever has to be done will be done by passing a generic config object like { actionsToFire: ['UPDATE_B'] }.
I need state management while navigating back and forth between the pages of the application, but I don't require hot-reloading, action-replay, or pre-fetching application state from server-side.
Components will also be responsible to destroy their state when no longer required. And state will have a normalized structure.
I know the requirements might seem weird or not-seen-often but I would keep them that way.
Few things I already know are:
I don't need to use Redux like the classic article from Dan says, but I think I need it here in this case.
I know about the Smart and Dumb components, mostly my components might seem smart (i.e aware of application state) but that is how I want to keep them, I might be wrong.
Diagram of the grid component:
Grid Component Diagram
Redux's global store makes encapsulation and dynamic plug-and-play behavior more difficult, but it is possible. There's actually many existing libraries for per-component-instance state and dynamic registration of reducers. (That said, the libraries I've seen thus far for component management are React libraries - you'd have to study some of those and reimplement things yourself for use with Angular.)

React nested Component, arbitrary communication

There are many answers regarding react component communication, but seems none of them resolved my problem. Here is my problem's detail. Please help! Thanks in advance.
I'm building a flexible form. The UI is generated by nesting components.
The form data structure could also be nested json objects.
i.e form can have some inputs and sections, sections can have some inputs or sections, and go on.
sections is just UI layout components, doesn't care about data or state.
But input (could be text input, checkbox etc anything to capture data)
The problem I'm facing is any input's validation could depends on any other inputs' value.
i.e inputA has validation expression like formData.inputB >formData.inputA + formData.inputC
But they could also have no dependency at all if you don't give a validation expression.
If I pass the whole formData down the component tree, every time I type in one input, the whole form will rerender.
I have considered redux, but real not sure how redux can help such case. I'm still relative new to react and redux, so I could be wrong.
So what could be a viable solution?
Its a common issue when you're modularizing form elements. I have the same problem.
Redux is by far the most controlled solution. All of the components can listen and update the same object simultaneously. But you can also attach functions as props from the parent that you bind to the parent. The function would fetch the state of the parent and update the state like a makeshift store. If you're a good developer, this is possible but neither are simple to do. Good time to learn :)
There are various solutions to your problem, but in general it shouldn't even be a problem, because rendering (even of large forms) should be quite effective with React.
The core tool for adjusting performance in React is the shouldComponentUpdate method of your component classes. If you're smart about what you pass to the individual form fields and then implement shouldComponentUpdate properly on them, you should be able to update only when needed. In your particular example, you don't need to pass the full object everywhere.
You can just pass value, onChange and isInvalid to each field and calculate the validity at the root (where you have access to the full state). Then the shouldComponentUpdate of your fields can decide just based on those props. (Obviously this is a simplistic example, but as a principle it's sound.)
Sure, Redux is another possible solution. If you keep the state in Redux store and only connect each of your fields to the portion of the state it needs, you should be all set. It brings quite a change in architecture though, so you should choose Redux only if you really want it for your app as a whole.

With redux, how do you avoid recalculating component state for complex pages?

Suppose a complex component is subscribed to the redux store. The first time the component is mounted, we aggregate a lot of data from the store and create a "ModelView" object.
Then, imagine that this component receive an event to update itself because there's a new state. It seems like the render method would need to re-aggregate all the data from the store to know if there's a difference. I.e. we cannot do a simple comparison because the ModelView object is different than what's in the store.
You may ask "Why a ModelView", why not just read data from the store in render(). This is a fine approach for simple pages, but for complex pages the lag is noticeable and it is just not possible.
Also, a view may have an internal state that is different from the store. For instance, maybe a few tasks have been updated in the store, but we don't want to change the UI because that would be confusing for the user.. we'd rather show a "Click to see new change" button for instance. One approach to that is to store everything in the store.. both the ModelView AND the normal state.. but isn't that overkill? Or said differently, shouldn't the ModelView be stored inside the component itself?
Computing Derived Data is a recipe describing how a memoized “view model” can be derived in a composable way from the Redux store thanks with Reselect.

Multiple Components Using One Store

What's the best way to handle a case where multiple components are using one store (which is populated by API calls in an action creator), but each component may need to access different sets of data without effecting the other. I.e.: two table components display data from the WidgetStore; one table wants all widgets, the other only displays widgets whose name contains "foo" (this would be based on user input). The table being queried via the API has tens of thousands of widgets, so loading them all into the store and filtering from the store isn't practical. Is there a Flux architecture (like Redux) that already has a way of handling this type of thing?
The simplest way is to just create a parent component and selectively hand off data, using a pluck or selector function, to each of the children.
For the more general answer for yourself going forward... if you follow something along the lines like redux there is already proven patterns which will help you understand passing complex data down.

Resources