Use cases for when not to use redux? - reactjs

I was always wondering if I should use redux store all the time even when it's not really necessary.
For example:
I have form with select field that has some options I fetch from API. Let's imagine that form is for adding new car listing and select options are car models. Should I directly call API from component and display options or should I create store CarModels or something like that and store results from API there and then map those values to state in component?
I have "Favorites" feature, when you click heart next to some item (let's say a car), do I need to go through dispatching all events FAVORITE_CAR_REQUEST, FAVORITE_CAR_SUCCESS etc... or is it good enough to just call API directly from component (using some kind of api-service of course).
It's related to question above. If I have screen where I show favorites, I should then probably have store and connect everything with actual favorite action so I update the list. On new favorite, API will return favorited item, should I push that one in list of favorites already in store or should I just load again latest list when user opens up the favorites screen?
Thanks in advance.

I think this is a perfectly valid question. What I feel like you're trying to ask is if you could/should mix react state and the redux store. The answer is sure! Just think about where you need to use that part of state before deciding where to store it. If you need a part of the state in multiple components, it probably makes sense to use Redux. If you only need state locally, perhaps to set form validation errors, maybe use react's state management if you feel like it. React and redux are both meant to be flexible, so as long as you're consistent in when you use the redux store and react state you should be good.
I found this article that also explains this pretty well: https://blog.jakoblind.no/is-using-a-mix-of-redux-state-and-react-local-component-state-ok/

I tend to use redux when the state has to be accessed globally / complex logic that i want to be logged properly

Related

Is there a React (state related) event pub sub pattern when replacing Redux?

It seems to me the trend is replacing Redux with React Context API and useReducer.
I personally do not like a huge store at root with states from user data to if a dialog is opened all mixed together.
Switching to React Context API allowed me to push the state down and closer to where they will be used. However I can only push it down to the level that child components are either displaying or modifying that value. For example:
<Parent>
<CounterDisplay/>
<CounterIncreaseButton/>
</Parent>
I have to have count on Parent and create a Context. Within the Context, I'll add the count value and an increaseCount method (or a state and a dispatch function when use reducer pattern). Then I provide the context to those 2 child components. Now one can display it and one can modify it.
Now what if I need another button located far from this part of the component tree that also need to change the count value? I have to lift the state up and maybe all the way to the root. That feels strange to me.
2nd issue is when states are scattered at multiple level along the path in the tree, when something happens say user click a button, you may need to call multiple functions from multiple contexts (or dispatch multiple actions, one for each state that may or may not change). Unlike when use Redux since everything is at the root, you just need to dispatch one action.
So what if instead I have an event pub/sub at the root level? I can have the counter state and code manipulate it pushed down even more to CounterDisplay. CounterDisplay need to subscribe to the pub/sub system and listen to the event and update counter correspondingly. And whichever component want to change the counter can just raise an event.
What am I missing in this pattern? Circular event loop? Raise conditions? Feels a good pub/sub library can prevent these. I looked around and did not find something existing. I looked at RxJS but don't feel that fits.
Thanks in advance for sharing your thoughts.
You've basically just described the exact reason for Redux to exist :)
Redux is "an event pub/sub at the root level", and can specifically be beneficial in cases where widely separated components need to make use of the same data.
You may want to read my post Redux - Not Dead Yet!, which describes how Redux fits into today's ecosystem (including comparisons vs context) and some of the reasons you might find it useful.
If you are put off redux by the amount of boilerplate.
I would suggest taking a look at redux-zero.
Under the hood. react-redux uses a context provider at the root.
When you use the connect Higher-Order-Component that is using the context.
Same with the redux hooks.
So it's quite normal to have the provider at the very top.
It would be the same for any library like the react-router to do the same.
I would suggest you keep trying without redux so you can learn more. Put the provider at the root. It won't impact performance in anyway.
Isolate the context you create and the provider to a singleton file and import it to the components you need

Initialize state from props using rehydrated Redux store

In my application I have a dialog window on which there are multiple input fields. What I want to do is to save user's input in the component's own state and only afterwards, say, inside "onClose" of the Dialog send the input to a redux store using "dispatch" function.
This way the dialog component would keep field data inside its own state.
The problem that I face is that I'm not sure what the best way is to rebuild dialog component state from information contained in the redux store.
If one refreshes the page with F5 or simply reloads it, then components lose their state and fields will appear blank, regardless of the fact that rehydrated redux store still contains valid input information.
The question is then, what is the best way to set components state from props? Moreover, doesn't it seem like an antipattern? What are some common techniques for such task?
One possibility is to set field values directly to those contained in "props". This would, however, imply that every small change of the input fields will result in copying and modifying redux store, which is slow & inefficient.
Usually building a state from props complicates code a lot, you have to map props both in constructor and getDerivedStatesFromProps.
I prefer to write component functions which return value based on passed props.
As you mentioned it may impact perfomance, to fix it you can use memoize-one library.
For more details you can check the following answer

react with redux folder structure dillema

I have a React-Redux app where I have several tabs, and I keep my code in a structure of folder-per-tab. Each folder contains an actions file, service file, constants file and a reducer file.
When I fetch the data from the server, I fetch it as one big nested object, whose top level keys are sectionA, sectionB, sectionC and so on.
Each tab may use data from multiple sections, for example, tab 1 may use sectionA and sectionB, tab 2 may use sectionB and sectionC and so on.
This creates a problem in the way I split the data into reducers. If the top level keys in the redux store will be "tab1" and "tab2", and I would want to update data in sectionB, then I will have to do it in two different reducers. On the other hand, if the top level keys would be "sectionA", "sectionB" etc, then my folder structure is wrong. Any way to solve this?
Thanks.
It sounds like you are thinking very much like a front-end developer, and categorising your state according to how it relates to the user interface.
You might want to think about how you are normalizing your state shape:
https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
Redux is really a tiny backend for your front-end. I'm sure the purists will debate this on a million levels, but it actually functions like a little, local document store.
Try thinking about your redux structure more in terms of what the data is, than where you want to put it on the screen.
the normalizr library is some next level-ness for that
https://github.com/paularmstrong/normalizr
I'm still debating whether I think it's too far. My app is starting to turn from an MVVC into an MVCMVCCVMMV... (you get it, some kind of epic roman numeral).
How much data do I want to keep in a pubsub model locally, vs always hitting my API server for that?
How long does a user leave a page open, filling the redux store up with new data until there's a memory problem?
Garbage collection in redux is a whole extra conversation, and this is worth a read: https://github.com/reduxjs/redux/issues/1824
Old mate Dan Abramov jumps in with some useful thoughts on that thread.
I realise none of this is an answer per-se, but it seems like redux has more 'use case scenarios' than answers generally anyway.

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.)

Better approach to create react-redux layout header component

I'm going to create a large scale application with react and redux and start to build the header component of the layout very first time. The layout header will have 4 child parts.
1. Icon that will show all the online users after clicking on it
2. Icon that will show latest 10 notifications after clicking on it
3. Icon that will show latest 10 messages received after clicking on it
4. Logged in user name that will be dropdown button to show some "My profile, logout, account setting" navigation links.
As I've read about redux at so many places that we must have as less as possible stateful components. So by keeping this concept in mind, I thought to have only one header smart container with a header state consisting default states for all icons like
{headerOnlineUsers:[], headerMessages:[], headerNotifications:[]}.
So if I follow the redux best practice and create only one smart header container with 4 different dumb components, the each and every time the state of any of them is changed, the whole header container will get re-rendered.
But I want to re-render only the state changed component.
For example, If I get a user joining the chat through websocket, It will dispatch an action and the reducer will update the headerOnlineUsers list of the state. But In this case I want my only online users component to be re-render not the whole header container.
Can anybody please suggest me the best approach to implement this kind of layout.
I would not go for your option, but would prefer a more granular approach.
What if you split the header in 2 later on, or want to display the button somewhere else ?
What if you have another version of your header for a subsection of the website ? You would need another container that gather again all the info.
The logic in general in redux is to separate what is data-sensitive and what is not. Your individual lists are data sensitive, the header in itself has no reason to be so far. What's more, if you want to attach actions to the icons it will quickly become messy to bring back thoses actions to the header and then its container, and even messier if you ever need to move them.
The way I would do it (and the way I do it right now as I halso develop quite huge app with react and redux), would be to have a store with those 3 lists of items, and then 3 containers, one for each icon/dropdown that links one aprticular list to the component.
Then the header is just a stateless function holding all the containers together. This way if you ever need to move one button somewhere else or reuse it, you just import the container and voila!
React.js will take care of only re-rendering what is required. So this problem is already solved for you :-)
What you plan to do sounds sane to me, I just would change one bit: The smart header container should not use internal state. Instead, your redux store should look like this:
{headerOnlineUsers:[], headerMessages:[], headerNotifications:[]}
and you should pass the redux store into the smart header container (have a look at the connect function in the redux documentation). This way, you can use the redux store contents in your component via this.props, and that's it.

Resources