I am new to redux/redux saga and I am trying to develop an app where I have two browsers interacting with each other via redux saga actions. Currently, I am able to dispatch actions within the same browser, but if I want to dispatch an action to the other browser, the app does not appear to be responding to the dispatched actions. I'm pretty much using the tutorial on https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html for my code.
Before I share my code I want to understand if it is possible to dispatch an action using redux to another user on a different browser. If so, can someone please help me understand how to do so?
You could establish a websocket connection to your server and subscribe to actions to dispatch on each browsers redux store (Publish-Subscribe).
Its not an easy task though. You will have to make sure the actions are dispatched in the exact same order in each browser, to make sure to keep the states synchronized.
Downside is, in order to maintain order, you will have to wait for your server to process your actions, and have no immediate visual feedback (or at least delayed by networking). So you will probably end up with two separate stores, or have to handle that delay somehow visually.
Related
I got confused with the right data flow when I have a backend API and a redux state that passing the data to the components.
The question is: What is the right methodology to handle 2 data resources, API and Redux?
should I update the state and then fire a send request to the API with the update?
or, let the redux send that request for me every time the state changes?
or, should I update the API directly and then fire a get request to update the Redux store?
I'm really confused and do not know what is right approach should I take with less error in the future use
Appreciate any help, even sending me an article that talks about this issue and I'm gonna read it
Thank you
should I update the state and then fire a send request to the API with the update?
That's called "optimistic update", the advantage is that your app feels fast and responsive, since the network delay is hidden from the user. The downside is that the request might fail and you have to undo what the user did and inform them that it failed. For simple operations (for example marking a product as a favorite in an ecommerce website) this works great in my opinion.
To explain how it works with the example in mind:
User action triggers update of redux state (product is immediately shown as favourite on the page)
At the same time, an API request is fired to favourite the product on the backend side.
You fetch the product data again from the API and render it
Now either the request has successfully changed the product, so visually nothing changes on the page for the user - to them it looks like the operation happened without network delay - Or the request failed and you show the old state where the product is not a favourite and and error message appears.
or, let the redux send that request for me every time the state changes?
Parts of redux-toolkit embrace this approach if I'm not mistaken. If you decide to go down this road, I'd recommend to not implement it yourself but instead rely on existing libraries/middlewares.
or, should I update the API directly and then fire a get request to update the Redux store?
This is the classic, safe, and simple approach.
My advice is:
If you have lots and lots of CRUD operations against your API, and you want to not write lots of boilerplate code, look into redux-toolkit (specifically https://redux-toolkit.js.org/rtk-query/overview ).
If you care about perceived performance of your app, try optimistic update.
If you want to keep it simple and just get things to work, follow the classic approach.
I am currently developing an app with Vue.js and Firebase database.
I am listening to real-time changes of one of the database documents, at the App.vue level.
In a child component, I would typically unsubscribe from the database in the beforeDestroy() Vue.js lifecycle.
Is there any point of unscubscribing at the App.vue level?
Thanks!
If you believe that all subscribes should have matching unsubscribes, for the purpose of code symmetry, and communicating to other readers of your code when the subscription is expected to end, you might choose to add that code.
If your code runs in an environment (perhaps a test environment) that does not fully get destroyed when the lifecycle is complete, then you'd probably want to make sure your app releases its resources correctly.
Or maybe you are just concerned if there is any chance at all a subscription might leak, causing you money over time as it causes reads when those reads will not be used, so you choose to clean up properly just in case.
I am writing a simple login page.
After user clicks on login button, I will be receiving a user authentication token if the login is successful.
I would like to store the token in to a simple sqlite storage.
Where should I put this logic? (The async opening db, updating db logic), I am currently putting them in the action creators for the SUCCESS_LOGIN action. But what does redux recommend?
There are multiple questions like this one:
How to handle complex side-effects in Redux?
How to handle side effects in react/redux?
Personally I use redux-saga, but redux-loop is also very popular.
If it's a simple application you could use redux-thunk or you are probably ok with your current approach, no need to add more libraries and boilerplate if you have all the functionality done.
I have a working auth flow for a React/Redux app, and I'm using reselect and redux-saga to handle state selection and async login/register functionality.
I have a single container that I've been using for testing, with login, register, logout all working. However, now I'm trying to figure out the "right" way to structure the app.
Should my login form and register form be their own containers with all functionality built in? If I do that, I find myself duplicating certain actions and code, such as the SET_AUTH action.
Is it "correct" to duplicate the code and separate the containers? Or is there some other way I'm missing?
I ended up creating my authentication containers and reducers globally, in my root container (App.js), and then just dispatching actions from around my app - since the sagas are global they're always available, and simply wait for the dispatched actions.
For managing state per container I ended up using reselect to grab state slices from various parts of the app.
I really need some expert help here!. Does anybody knows of a way of getting the list of the users currently connected to a BlazeDS server? Is there any built-in mechanism of knowing this? or do I have to implement some kind of server side logic every time a user access my Flex application and store all logged in users details somewhere and retrieve them later?
The nearest thing I can think of, using BlazeDS, is to obtain a list of clients currently subscribed to a destination, but this won't solve the problem IMO.
First of all, you need to define a destination and make sure that all clients will actually subscribe to it (see BlazeDS documentation for this). Then, on the server, you can then get a reference to the message service
MessageService messageService;
messageService = (MessageService) messageBroker.getService("message-service");
and ask for all subscribers with the getSubscribersIds method on the MessageService instance, specifying the name of your destination. This will only returns a number of identifiers, internally generated by BlazeDS (they are also available on the client side of the connection).
To resolve the same problem, I used this approach in combination to a custom server-side logic to store logged-in users (explicitly invoked login/logout methods). Regularly looking at the subscribers can help to clean this store, because in my experience there's no way to be sure that a "logout" method will always successfully called, expecially from Flex client running in the browser, while BlazeDS will automatically take care of cleanup of the subscribers.
I don't like very much this approach, probably someone came up with a better solution..