I am researching into what is the best way to store the UI state, Should I use something like Redux-UI (https://github.com/tonyhb/redux-ui) to store/manage the UI state? or should I create my own actions/reducers for the UI?
Also...
when I have stored the UI state, how do I make sure if the browser is refreshed, I still have exactly the same state of the page? Just as a normal web page would including Data taken from the server.
I have Redux with thunk middle wear implemented and a store. I have worked with React for the past couple of months thus far.
Thanks!
Quinton
Our team has spent some days on this. The reasons we want UI states, instead of putting those states to Redux's state tree, can be:
Those UI states are only relevant to a very small number of components. But yet sometimes we need to share those states amongst them. For example, a Button to control a Modal, they both need to read/write the 'isModalOpen' state.
Those states are not data, they are UI preference and it is fine to reset them to the default upon component unmount. Persisting them in the single Redux store sounds like polluting the state tree.
We tried:
Creating a separate redux state tree just for UI.
Add a main branch, say 'state.UI' for all 'UI' states.
However, all these involve having to use/implement custom middleware, actions and reducers. Hard.
At the end, I made react-provide-state. It works really well. The only drawback of it is your can not easily see the ui states like states in Redux tree in browser console. And you can only update states through UI (user action event callbacks). That's fair, it is UI states we are talking about.
Related
So Basically, I came across many articles where they are referring to manage state via flux or redux.
I wanted to know that how about UI component having its own state? Is it good practice to let redux manage the Api call and success toast messages etc. but UI components should have their own local state?
Kindly someone elaborate what is the best practice in industry?
Though the question calls for opinion, I am going to leave my answer. There is no standard best practice regarding this. It boils down to convenience and ground rules of your team, if there are more than one people writing the code.
I use Redux quite a lot. However, I won't refrain from using local state in components.
Form handling like input onChange handlers require local state. It is not performant to use global state for onChange handlers.
Reusable component uses local state. Again, it boils down to whether the reusability is a technical reusability or business reusability. If you are developing a custom scrollbar component, use local state. However, if you are using a comment form which is used everywhere in your application, use global state.
I prefer to have most of the stuff in global state. I use redux thunk as well. In redux thunk, it is possible to access global state within the thunk function. This is quite useful as it avoids the reliance for props / context being passed all around.
I do keep some simple things in local state -- for example, show / hide some stuff. I don't mind waiting for promises to resolve before hiding some stuff using local state.
Overall, the decision to use global state vs local state is primarily based on convenience. There are no standard rules other than what you and your team are comfortable with.
React is a way to declaratively deal with UI. There are some rules of the framework like state, props, context. It is left upto the developer to make the UI declarative and performant based on these primitives. How, a developer does it does not matter as long as the code is maintainable and understood by others.
After asking many professionals and industry developers, I came to know that managing state through redux depends on your application scope.
but more importantly, If I am working on enterprise Application then the application state must be managed through redux.
Now the question is what should be kept in our redux store. well, you can store almost anything in redux store but better to manage the local state of a component as well. for instance, opening a component Boolean should be managed in local state or any string or header name etc.
Good question! The answer is usually "it depends", but there are clear cases when you'd probably prefer to use one over the other.
Use Redux for storing state relevant to the application. E.g. the current page/panel that should be shown. As you mentioned, showing a notification/message - is something that'd make sense to store in redux state, as the alternative would be passing state all over the place, e.g. an error prop bubbling up to your root component which renders the toast message. Using thunk is also a good idea when you're fetching/manipulating data relevant to the whole app, e.g. a list of things that appear in several places.
Use component state for storing state only relevant to the component. That is, if you're filling in a form, it makes sense to store the value of text inputs, checkboxes etc. in your component state (perhaps in conjunction with container and presentational components) as the values at this point aren't relevant to the rest of the application.
I have often heard questions that ' Why one should use redux whether there is also a State in the ReactJs. Which extra facilities redux does provide to the developer ? '
For small applications when there aren't a lot of components, you can do without redux. But in large applications, it becomes pretty complicated/tedious to chain props through components especially if one that is deep 6 levels needs it.
This is a great article that explains it
https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835
The Redux docs page about organizing state (here), list out a few reasons one might lean to using Redux store over component state. However, they do clearly state that "using local component state is fine" and that, in the end, the developer should find the proper balance for the work at hand.
Some common rules of thumb for determining what kind of data should be put into Redux:
Do other parts of the application care about this data?
Do you need to be able to create further derived data based on this original data?
Is the same data being used to drive multiple components?
Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)?
Redux is required when your application is big with many components. Redux works as global meaning if you set value in one component you can get that value across components. This is the primary advantage with state management Library.
If your application is small with 10 to 20 components then we don’t need redux. We can pass down state to child components as props but when application grows big you will have so many components and it’s very difficult to play with component level state and you won’t have control of the flow and you can’t track of values between components
So redux is very useful in such cases.
I watched the Getting Started with Redux series and am working through modifying my existing React code to use Redux. However, I've run into a dilemma that I can't seem to find any answers for: I want to modify the store data (which many of my React components will use) on particular events such UI interaction, but I don't want any UI components to subscribe to every change made to the store.
Can/should I instead make a separate .js file with functions that can access the store directly to call .getState() and .dispatch() which my UI components can import and call when needed, instead of subscribing to the store themselves?
Or am I fundamentally misunderstanding something and subscribing to the store would have exactly the same effect? I'm aiming to optimize speed; that's why I switched to Redux.
I want to modify the store data (which many of my React components
will use) on particular events such UI interaction, but I don't want
any UI components to subscribe to every change made to the store.
Checkout react-redux, it's the official binding for react and redux apps. It provides a way to subscribe specific components to redux and only listen for the changes that you are interested in. On top of that it also implements various optimisations to avoid unnecessary re-renders.
Can/should I instead make a separate .js file with functions that can
access the store directly to call .getState() and .dispatch() which my
UI components can import and call when needed, instead of subscribing
to the store themselves?
You can do anything you like, but don't be surprised if it becomes unmaintainable after a while.
Or am I fundamentally misunderstanding something and subscribing to
the store would have exactly the same effect?
Yes, you could use react-redux and only subscribe to parts of the store that you care about.
I'm aiming to optimize speed; that's why I switched to Redux.
Not sure what your particular situation is / was, but in general the point of redux is to provide a predictable and manageable way of maintaining an applications state - it doesn't directly speed up anything.
I have been using vanilla React for a while, and have now decided to take a closer look at Redux for a new project I am doing.
At first I got the impression that all user activity should result in actions, with one of the main reasons being that you would be able to reconstruct any application state by just playing back the appropriate actions.
The problem with this, however, is that you put a lot of stuff in the store that in reality does not feel like application state. Stuff like "If I focus on this input, the label turns green" does not seem like state fitted for being represented in the application state of an application that is potentially composed by hundreds of components. These things make total sense with the typical todo-tutorial, but it can be difficult to see how it will turn out in a more complex scenario.
Then I read some more, and found that the general opinion, backed by creator Dan Abramov, is that you should usually combine local component state with the application state (store). "Whatever seems least awkward" seemed to be the rule of thumb for where to store state.
On one hand this makes total sense: The things that are really application state, and are relevant for multiple components should be in the store, while the strictly presentational details that only concerns one single component should be handled using normal react state. On the other hand this approach confuses me a bit, because of what I wrote in the beginning: Isn't a big part of the point with redux that you avoid having the state distributed among the components, and that you are able to recreate state by just storing the actions?
I hope someone can shed some light on this concern, because it has been bothering me, and it is something I think I should get a solid opinion about before trying to build something complex with redux.
What state you put where is entirely up to you. Sometimes it may make sense to put everything in Redux, sometimes it may make sense to keep stuff in a component. I recently saw some good rules-of-thumb:
Do other parts of the application care about that data?
Do you need to be able to derive further data from that data?
Is the same data being used to drive multiple components/features?
Is there value to you, to being able to restore the state to a given point in time (ie: time travel / debugging)?
Do you want to cache the data, ie: reload it from state if it's already there instead of requesting it again?
(Credit to https://www.reddit.com/r/reactjs/comments/4w04to/when_using_redux_should_all_asynchronous_actions/d63u4o8 for that list.)
Also see the Redux FAQ on this topic: http://redux.js.org/docs/FAQ.html#organizing-state-only-redux-state .
In Flux every action should be handled by the dispatcher.
What about an action that doesn't alter the view or the markup, such as "scroll this element into view"? What is the "Flux-way" of handling such a scenario? To by-pass the dispatcher? Or to handle it in the dispatcher without involving the stores or the components?
Flux is really more about application state management, and is not at all about the details of what components are rendered in the view. That's the domain of React. Flux simply assumes you have some kind of reactive view layer -- usually that's React.
Application state is not the same as component state. Application state is something that needs to be known in multiple components. For component state, React's this.state is perfectly adequate. An input component is a good example of something that might need this.
So in your case, if only one component needs to know the scroll position, there may not be a good case for moving that state to a Flux Store. But as soon as that needs to be known in multiple components -- especially components in different branches of the tree -- you probably want that state being managed in a Store.
The other issue your question raises is the role of Flux Actions. A Flux application always uses Actions as the origin of the data flow. There are a lot of good reasons for doing this: stable application state, keeping the app resilient to new features, keeping it easy to reason about, undo history, reconstitution of application state, stateless view components, etc.
Occasionally people want to write as little code as possible and they use a callback passed between components to change this.state in the parent component instead of dispatching a new action to go through the Flux data flow. I find this to be mixing the view and state management layers of an application, and while expedient, this can lead to a lot of headache. It isn't very flexible in the long run, because now the state is coupled to these few components. Building up a Flux data flow from the start is much simpler in the long run, and much more resilient to new features. That said, it also requires more investment in code up front.
If your app doesn't need to know about scrolling (seems rare that it would), there's no need to fire an action. Since Flux is really there to handle data flow (and subsequent changes based on that data flow), it doesn't need to know about every action that occurs.