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.
Related
The question is probably more theoretical.
I have little experience with Vue and am trying to figure out where my knowledge gaps are and fill them.
There are standard mechanisms for interaction between components:
from top to bottom - input parameters (props) are passed from parent components to child components
from bottom to top - events are thrown from child to parent
And on the other hand, there is VUEX with its own data storage, which is, roughly speaking, a global variable object with a set of methods for working with it.
Data from this storage is available at any time to any component. And it turns out that the use of Vuex seems to make the standard interaction mechanisms of components completely unnecessary.
Well, perhaps, the generation of events is still needed so that one component can quickly make it clear to the other about the completed action, events, etc.
The question is, does Vuex generally override the standard component interactions?
If it is not, how should it be combined in the right way?
I'll try to answer your question.
Vuex will be very usefull to store data that you'll need in a part of the application or globally, like user data.
If you can simply use $emit or props use it, it will be better and simple to understand the code, because it will be overkill to use the store just for "a prop".
So, you will use Vuex in your component to call an action and fetch / store some data you will need in a another view out of your children/parents context.
I don't know if my explanations are well haha, I tried :)
I'm quite new to React, and I'm making a single page application with React.
So far, I've build the application with components and child components, having their own local state, however the child components doesn't really interact with one another, which is what I want them to, basically, with the least amount of boiler plate code...
The problem I'm facing, is that a change in some child component, should be able to update the state of another child component, somewhere else in the component tree.
A selection in one child component should also be able to trigger a function in another component updating it with data and so on.
I've considered having just one global application state, that all components can call and update when something in them changes, and this one application state will then update other components in the tree. Kinda like having a single "controller" with it's own state, that all components "views" can call, and which updates the states of other components as needed. (I'm used to WPF and MVC style of GUI programming).
What I've considered:
One could try to implement this with callback functions defined in the top of the hierarchy, to be sent down through the hierarchy and called from a child component when it changes.
This method however results in a LOT of boilerplate code that just passes functions to their child components. It feels wrong and hard to maintain...
To avoid all this passing around and boilerplate code, I've tried using a React Context, however this is not working as well as I hoped. I can only access the context from within the render function and from lifecycle functions, and sadly I often get complicated errors that are hard to understand. It seems like I'm exploiting React Context to do something you shouldn't use it for...
I've considered using a singleton pattern in JavaScript, however then that singleton needs to have a reference to the root component, and query for the component it needs to change... This seems like kind of a hack, and may not be that pretty, but idk.
I'm considering trying out React Redux however it seems to work in many ways similar to React Context (I'll be honest, I haven't read much into it yet).
What I need:
I need to ask someone with greater React experience than me: How do you keep a global application state, and update child components based on changes to the global application state? Also: Am I thinking about this all wrong? Am I trying to do something in a non-react way, failing to see how I should do it in React?
You can happily go with Redux or MobX, they're fine.
I suggest Taming The State from Robin Wieruch: https://roadtoreact.com/course-details?courseId=TAMING_THE_STATE
There are the book and the course. He shows different ways of handling React state.
Redux was created specifically for the problem yo stated.
Reacts follows a top-down down-top unidirectional flow in essence. Context API is useful in simple use cases but would fail horribly in a large scale application where you'd be creating consumers everywhere.
I'd suggest investing some time in Redux so that will save your precious time in long run.
There's a reason all big three frameworks require a state management library to be useful for large scale complex apps. (Angular has NgRx and Vue has Vuex).
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've been reading and watching videos on Redux and seeing a lot of debate about managing state in components or with Redux. What I'm not seeing is anything about managing state completely outside of components with standard global variables.
For example, I could set a global state variable like this:
let state = {
player: {
username: "BillyBob",
score: 100
}
}
Then in a React component, I could have something like this:
incrementScore() {
state.player.score += 1
props.update()
}
Then in App.js, I could have this:
update() {
this.forceUpdate()
}
I realize that I'd still have to pass the update function down through the tree, but I'd at least be able to set functions at the component level and not have to worry about passing multiple pieces of state and functions to child components.
I'm new to React, but the only downside I can think of is not being able to require propTypes. Is there anything else I'm missing?
EDIT: Per request that I clarify the question, are there any major downsides to the implementation above that I should be considering that would affect even a relatively simple app?
If you look at the implementation of redux or some other state management library out there (for example mobx or mobx-state-tree), basically all of them maintain the state outside of the component as a standalone object.
However, to detect changes and trigger re-render efficiently, they implement a HOC, it's connect in redux and inject in mobx, what the HOC (higher order component) does is to wrap your component inside another component that have access to the global state, and pass the part of the state require by your component via its props. This way, the component only re-render when the data required by it changes.
Compared with these popular library approach, there are couple problems with your proposed solution.
The first is using forceUpdate, basically, the last thing you might want to do is to call forceUpdate on the root node of your app, think about scenario when someone type in an input and the whole app re-render every single keystroke.
The second will be passing an update function down to multiple level of children, it will be fine if you have only 1 or 2 nested component, but will be a big problem one your app grows. As your app grows and your state become more complex, it might not be the best idea to have a single update function to control the whole state object.
React exists to solve the problem of creating a user interface that is composed of several indepentent pieces that can be developed in parallel and can seamlessly interact with each other.
If you are going to use global namespace to define your state then you are going to bypass most of the key features of React such as:
1. Lifecycle methods
2. Virtual DOM
3. Controlled Components
4. Rendering Optimizations
In a nutshell, you are going to end up with all the overhead costs of running React while missing out on its benefits.
The 'catch' in learning a new framework or paradigm is to understand how to define the problem in such a way that it leads to path of least resistance. This can be achieved by introducing a constraint and then solving the problem within that constraint.
By favoring vanilla JavaScript for state management, you are not giving React and Redux a fair chance.
I've created a library exactly for this use case :)
Simple 💪 fast ⚡️ and small 🎈 (500 bytes) global state management for React which can be used outside of a React component too!
https://github.com/web-ridge/react-ridge-state
Stick to redux, dont complicate things for yourself :)
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.