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.
Related
I'm very new to React Native (did some courses) and now building my first app on my own which is going great, but I need some advice regarding user applied filters and how to handle this.
Quick summary of what needs to be done.
The user should be able to set some filters so only certain data is displayed and this state is saved even after closing the application, user logs in again and still sees only the data that is filtered because of the filter option he/she set before.
In one of my courses I got an introduction into Redux and my question here is should I use Redux for this feature or maybe Context for this ? My data is fetched from Firestore and I'm able to use a query to filter data from firestore but that just ends up in many read/writes which cost money.
All advice is more than welcome!
use redux
when you need some static state globally in your app then use context like open close drawer etc. For dynamic states go for redux
As mentioned in stackoverflow answer :
As Context is no longer an experimental feature and you can use
Context in your application directly and it is going to be great for
passing down data to deeply nested components which is what it was
designed for.
As Mark Erikson has written in his blog:
If you're only using Redux to avoid passing down props, context could
replace Redux - but then you probably didn't need Redux in the first
place.
Context also doesn't give you anything like the Redux DevTools, the
ability to trace your state updates, middleware to add centralized
application logic, and other powerful capabilities that Redux enables.
Redux is much more powerful and provides a large number of features
that the Context API doesn't provide, also as #danAbramov mentioned
React Redux uses context internally but it doesn’t expose this fact in
the public API. So you should feel much safer using context via React
Redux than directly because if it changes, the burden of updating the
code will be on React Redux and not you.
It's up to Redux to actually update its implementation to adhere with
the latest Context API.
The latest Context API can be used for Applications where you would
simply be using Redux to pass data between components, however
applications which use centralized data and handle API requests in
Action creators using redux-thunk or redux-saga still would need
Redux. Apart from this Redux has other libraries associated with it
like redux-persist which allows you to save/store data in localStorage
and rehydrate on refresh which is what the Context API still doesn't
support.
You can refer to the blog1 and blog2 in order to get more clarity on when to use redux and context.
We are building a to-go order web application for restaurants with Firebase and Vue.
Restaurants can create their own pages, and add menu items.
Users (customers) can orders some foods from those restaurants pages, and pick them up later.
At the beginning of the project, we have chosen to store some transient data (user data, shopping carts, etc.) in the Vuex store. It works fine but there are a lot of complexities in it, which made it hard to maintain.
Recently, I have realized that we could just use Firestore for those transient data as well, which will greatly simplify the architecture, eliminating Vuex completely.
Before making all the changes, I want to make it sure that I am on the right track and I am not missing anything.
I'd really appreciate any comments and suggestions from those people who have experience in building relatively large scale web applications using Firebase + Vue (or even React).
Short Answer
Yes, this seems perfectly reasonable.
Long Answer
Many web applications have their state synchronized via an external service like Firebase, GraphQL, etc. In these cases you may already be using some kind of shared, UI-independent cache (e.g. Frestore, Apollo client). Unless the aforementioned cache cannot be easily accessed by your UI components, there would be little benefit to switching or duplicating the data to Vuex.
Keep in mind that even in the above scenario, Vuex can still be a useful tool to track UI-specific state across otherwise disconnected components in your interface. For example, you could globally identify the user's current viewing mode, or which modal is open.
Yes you can go without VUEX, however, it will limit your potential.
First of all vuex is really simple, you can easly add vuex your code.
Without Vuex you may write same code again and again.
For example you want to redirect your user to his restaurant page when he logs in. So you write a code that first checks if user has a restaurant and then gets his restaurant ids.
Also you want to check when a user opens a restaurant page, if the user owns that page, you write the same code again. However, if you have a function that returns a value if user is the owner or not. You can call it any page you want.
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.
(this was originally a post on the flutter-dev reddit that was redirected here)
So I started making this flutter app using firebase as a backend and after looking at all the options for state management I finally realised that the tools provided by firebase already handle pretty much everything I would need state management for.
For example:
I could set the currently logged in user in my state to show the right login or home page and make the user uid available to widgets for their firestore API calls.
OR
I can just listen to FirebaseAuth.instance.onAuthStateChanged to show the right page and just use FirebaseAuth.instance.currentUser() from anywhere to get the logged in user uid and do my firestore calls.
What I mean is, for every thing that would require global state, I can just basically have a firebase stream listener.
Is this right ? Or am I missing something here ?
You're not missing anything. Since most Firebase APIs rely on data from Google's servers, many of them are designed to be used in a reactive way. Making your UI reactively respond to those asynchronous changes is (in my experience) the best way to keep your code simple.
There may be slight behavior between the different types of listeners. But the onAuthStateChanged listener immediately fires with the current state when you attach it, which makes it a good example of a listener that you can use everywhere you need to respond to auth state (instead of also storing that state somewhere in your app).
In that scenario I would say yes, you can read the onAuthStateChanged stream and react to changes. But there are also scenarios where I need a stream for interacting between widgets without a parent/child relationship. For example, in one of my apps I have a company selector, and the rest of the app reflects to the selected company. I created a stream, so that the company selector doesn't need to be a parent of the other widgets, and especially so that I don't need to pass the company parameter to all the widget tree.
I also have one scenario where I need to load extra information about the user that isn't available on the FirebaseUser object. So when the user is logged on I load their information from a "users" collection and then I add that to a custom stream.
So to conclude I would say yes, you should use the default Firebase streams when possible, but that doesn't mean you can or should use that solution for everything.
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.