I just recently got introduced to Redux and decided to learn how to implement it. At the moment I'm refactoring some of my previous studying-projects and implementing the global state logic provided by the tool.
The thing is, I've recently stumbled upon the thunk middleware for async actions and got curious about something that's probably a simple concept misunderstanding but that I just can't get over.
So, why would I dispatch an async action? I just can't see the benefits of doing that way instead of waiting for the execution of whatever I'm doing and just then dispatch the action carrying the data I want.
Using a simple fetch call as an example, why would I not do the following:
->await fetch data
->dispatch fetched data
And instead do this:
->dispatch action
->await dispatch action
There's probably some use cases that I don't know of because for me, a beginner, sounds like extra code for something that maybe didn't require it? Idk.
Could someone help me? =)
Yep, as you found, that's Dan Abramov's original explanation of why something like the thunk middleware exists.
I recently wrote a new Redux docs page on Writing Logic with Thunks, which goes into more detail on the purpose behind thunks and how to use them correctly. I'll quote from the "Why Use Thunks?" section:
Thunks allow us to write additional Redux-related logic separate from a UI layer. This logic can include side effects, such as async requests or generating random values, as well as logic that requires dispatching multiple actions or access to the Redux store state.
Redux reducers must not contain side effects, but real applications require logic that has side effects. Some of that may live inside components, but some may need to live outside the UI layer. Thunks (and other Redux middleware) give us a place to put those side effects.
It's common to have logic directly in components, such as making an async request in a click handler or a useEffect hook and then processing the results. However, it's often necessary to move as much of that logic as possible outside the UI layer. This may be done to improve testability of the logic, to keep the UI layer as thin and "presentational" as possible, or to improve code reuse and sharing.
In a sense, a thunk is a loophole where you can write any code that needs to interact with the Redux store, ahead of time, without needing to know which Redux store will be used. This keeps the logic from being bound to any specific Redux store instance and keeps it reusable.
The Redux FAQ entry on "why do we use middleware for side effects?" links to additional information on this topic.
Recently I found this library: https://easy-peasy.vercel.app/
Implemented it, and must say it was quite nice. Why it is not so popular as redux? why people tend to use redux when they can use this? What are the advantages and disadvantages of both?
Also wanted to know how immutability of state is conserved in easy peasy when I can do things like that:
addProduct: action((state, payload) => {
state.productIds.push(payload);
})
clearly it mutates the state.. Maybe it doesn't mutate the actual state?
In general wanted to know if all redux principles are kept, and what are the main differences between the two?
easy-peasy is an abstraction over Redux, and it uses Redux internally to manage state.
Some people would choose to use Redux as they would have complete control over how actions, action creators, reducers etc. are implemented. However users of easy-peasy are given an opinionated way of using Redux, which cuts down drastically on the amount of boilerplate you have to write to work with it.
As for how it enforces immutability in the reducers, whilst the code being written looks like its mutating the data, easy-peasy actually uses Immer "under the hood"; quote from the Immer website:
"The basic idea is that you will apply all your changes to a temporary
draftState, which is a proxy of the currentState. Once all your
mutations are completed, Immer will produce the nextState based on the
mutations to the draft state. This means that you can interact with
your data by simply modifying it while keeping all the benefits of
immutable data."
As is stated on the easy-peasy website, the library allows the extension of the underlying Redux store, which allows you to plug in vanilla Redux middleware/enhancers.
Hello everyone Im doing a search bar using react and got a program, before I was passing data between components parent > child, child > parent but now I need to pass from my src>components>toolbar>search bar to src>containers>category component, someone could help me?? thankss
Another way to achieve this, by creating and dispatching an event and listing this in a component.
componentDidMount() {
this.nv.addEventListener("custom-event", this.handleNvEnter);
}
componentWillUnmount() {
this.nv.removeEventListener("custom-event", this.handleNvEnter);
}
handleNvEnter = (event) => {
console.log("custom-event:", event);
}
I looked at your question and the first thought that came to my mind was introducing Redux.
You can do this by installing a few packages using npm.
Redux (core library for Redux) Redux documentation
React-Redux (Redux is a apart from React and needs this package to work cohesively) React usage with Redux
Honestly I could ramble on and tell you how to integrate every little detail. But I'm not going to do that instead I'll give you an overview of how you would use this technology to your benefit. Be warned this is going to require a bit of time to master, however in doing this your ability to design complex systems will be greatly enhanced.
Firstly, you're going to want to learn a bit more about how Redux stores and data. Here is an introductory course by Dan Abramov the creator of Redux Redux course. It isn't too long and is free!
Once you're familiar with stores, reducers, action creators, actions and the Provider component --->Close your laptop<--- and take out a pen and paper and map the hell out of what belongs where. For instance, your search data belongs in a reducer that handles it, and your going to have to design your actions accordingly too plus read their payloads and map them to the store.
Now code it. With the design being completed and necessary information on how to develop with redux, this should be a stroll in the park.
Hope this helps your question.
I think the best way to solve that problem is to use Redux (https://redux.js.org/basics/usagewithreact) which is typically used for storing the values and which you can use it throughout the application files.
The below links will help you understand Redux and how to implement to your react application:
https://github.com/bradtraversy/redux_crash_course
https://www.youtube.com/watch?v=93p3LxR9xfM&t=537s
https://github.com/bradeac/using-redux-with-react/tree/master/src
You can pass the data up to the topmost parent and then pass it down again to the child you want to.
I want to know, what would happen if I change the state from else where like say from component directly or from getter function ?
Basically you could do that and probably all subscribers will be notified and nothing bad will happen, but the thing is that when you are using Vuex you agree to follow some design pattern proposed in there. Nothing would stop you from implementing your simple store (with only state and actions) that would share the state with vuejs and use it's reactivity. It would work- the thing is that Vuex is- as I said- a pattern that shows you the best way to track your changes and debug your app. In future your app's state may grow and I am assured that you would like to know what exactly is happening under the hood- thus you have mutations that have a simple task: update the state and help to track that exact change.
Using https://github.com/vuejs/vue-devtools you can easily see the transactions being done under the hood which would help others (or you in the future) what is going on with the state. Also, with mutations you are writing some kind of possibilities what in your state and how can be changed. Think of it as an API to access your data- no random or untrackable changes.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I have recently started learning React and I quickly encountered the problem of a bloated parent component full of functions and state. At first I looked at Flux and then I looked at Redux but both seemed like really overbearing solutions.
I am wondering why something like this is not done:
//EventPropagator.js
let EventPropagator = {
registerListener(listenerObject){
if (this.listeners == null)
this.listeners = []
this.listeners.push(listenerObject)
},
fireEvent(eventObject){
let listenerList = this.listeners.filter(function(listener){
return listener.eventType === eventObject.eventType
})
listenerList.forEach((listener) => {
listener.callback(eventObject.payload)
})
}
}
export default EventPropagator
To use: components simply registerListener and fireEvent:
//main.js
import EventPropagator from './events/EventPropagator'
EventPropagator.registerListener({
"eventType": "carry_coconut",
"callback": (payload) => {
// actually carry coconut
this.setState({"swallow_type": payload.swallow})
console.log(payload)
}
})
EventPropagator.fireEvent({
"eventType": "carry_coconut",
"payload": { "swallow": "african" }
})
This would allow a lot of decoupling and state could easily be passed around with this sort of event. What are the downsides to this approach?
You should try mobX
mobX is a state management library which took the advantage of decorators and succeeded in removing unwanted code. For example, there is no concept of reducers in mobx.
Hope this helps!
There is Reactn based in hooks.
It is orders of magnitude easier to use, compared to Redux.
Check https://www.npmjs.com/package/reactn and read Stover's blog.
Redux is a continuation of React's declarative programming Style. A simple way of mapping your application logic to components is to use something like Backbone.React.Component but using redux, will let you use all the tooling & middle-ware. Also have indefinite transitions in your apps makes debugging a lot easier. Now, I agree that you need a lot of wiring & boilerplate to get anyway.
If you want to use redux, you could look at something like redux-auto
Redux-auto: Redux made easy (with a plug and play approach)
Removing the boilerplate code in setting up a store & actions. why? This utility to allow you to get up and running with Rudux in a fraction of the time!
You can see now a redux-auto: helloworld project
If you want to take advantage of all the Redux benefits, use Redux.
If you only want to keep a var on sync between React components, use Duix.
I'm the Duix's creator. I've been using it for 1 year, and finally, I released it a few hours ago. Check the doc: https://www.npmjs.com/package/duix
You should try Hookstate. It gives the same simplest API for local, lifted, and global states. First class typescript. DevTools support. Extendable with plugins. Comprehensive documentation. It has got state usage tracking feature and smart re-rendering of only deeply nested affected components. This makes it the fastest state management solution for large frequently changing states. Disclaimer: I am maintainer of the project.
What is needed is an event driven system so a child component can speak to its sibling but this does not mean that data should be passed as the events payload. That would lead to a system of no governance and a nightmare for a project where multiple developers are working on it.
So long as you follow the flux-like architecture pattern (google it) then you actually can do this successfully with just javascript and Javascript objects to hold the data along with the event system.
Data should be treated as being one of three different states. It's either
original data pulled from the server
transformed data (transformed from the original)
Store data. That which acts as the model which the UI is bound to
If you write a javascript library to handle the movement of data between the three states and handle the transforms you can use the event system to to fire a "store changed" event that components can listen to and self-rerender.
https://github.com/deepakpatil84/pure-data
Note: i am the author of this
Using your EventPropagator solves the problem of communication, but does not handle data integrity. For example, if there are more than 2 components listening to same event, and using that event's payload to update their own states. The more components listen to same events, the more complex it is to make sure that all those components have same data in their own states.
Secondly, Flux/Redux provides uni-directional data flow. A simple example could be about 2 components A & B, consuming same data X from external source (API or storage). User can interact with either of them to get latest X data. Now if user asks B to update X, we have 2 solutions with your EventPropagator:
B will update X itself, and fire an event to inform A about the update to let A re-rendered. Same goes for A if user asks A to update X. This is bi-directional data flow.
B will fire an event to A asking to update X, and await A to fire an event back to get updated X. If user asks A to update, A will do it itself and inform B. This is uni-directional data flow.
Once your number of components goes large and communication is not limited between only A & B, you might need to stick with only one of those 2 above solution to avoid your app's logic going wild. Flux/Redux chooses the second, and we are happy with that.
If you really don't think you need another library for data control, you should look at the newest feature of React: Context. It provides most essential features that a data control library can have, and it's React only. Noted that you have to update your project's React version to 16.3 to use this feature.
Another modest multi-store alternative is react-scopes
Here are some features:
Simple decorators syntax,
Allow defining independent store logic directly in Components
Easily connect stores through the Components tree
Allow templating complex / async data process
SSR with async data
etc
I wrote Reducs. It's only 25 lines of code, it doesn't require boilerplate, and... did I mention that it's only 25 lines of code?
I am using it for a big project, and it's holding up very well. There is a live example that uses lit-html and Reducs.
I faced similar issues, with lot of switch, case, etc...
I create for myself something as alternative, you could take a look:
https://www.npmjs.com/package/micro-reducers
Take a look on JetState for state management with RxJS. I wrote this for my Angular projects and later adapted it for using with React's hooks.
PullState I really want this underdog to shine. Tried other similar ones which promised quick and no-boilerplate-ness, none came close to the ease of use of PullState. I just read the first page of the documentation and implemented it in one of my pages and it just worked. It is easy to understand if you already using functional components in react.