So, I am making an application on react-native. People login and then they can move around, however, the login value will be used many times through the story. I am currently sending the id as parameter during movement time after time, which is not very efficient, as not every screen uses it. What is the best way to keep it available across the application, since I was told that global variables and singletons are dangerous to use.
Redux is perfectly designed for that.
It offers a global state for your application, that every component can access through their props.
You can store access token, user infos, and many other variable in it.
I am currently making an app for both web and iOS and on the web side I have a bunch of logic in Javascript that alters a Firestore database I have. I figured I would move this logic into multiple cloud functions so that I can call them from both my web and iOS client and only have to write the logic once, in nodeJS instead of writing the same logic once for the web app in Javascript and once for the iOS app in Swift. I have gotten the cloud functions to work and update the database but the problem is the cold start times. I have UI elements on my webpage that watch for updates in my Firestore database and change whenever there is a change. Before these changes would be instantaneous but now with Cloud Functions I have to wait for the cold start to finish before the database is updated and thus the UI. This leads to it looking like the UI does not react to inputs immediately.
I wanted to move to cloud functions so I would only have to write the logic once but is this a use case that will not work? (Updating UI elements in real time). Is it worth while trying to set up a cron job to keep pinging my functions to keep them "alive" at all times? How do I increase the functions "alive time" after a cold start since mine seem to die fairly quickly? Any general tips or tricks on tackling this problem?
Thanks guys.
You can't effectively control the cold start behavior of Cloud Functions. This is something you will have to accept as a tradeoff.
The only thing you can effectively do is minimize the amount of work in the global scope for your functions and move that work inside each function as necessary. This creates a situation where each function has its own cold start behavior, which is not shared or duplicated among all your functions.
I am in the process of creating a mobile and web version of an app using ReactJS and iOS respectively. Both of these platforms will pull data down from a Firestore database to use but I am wondering what is the best way to only write business logic once in order to do operations on the database?
For instance, on both apps you will click a button that updates a field in the Firestore database, instead of writing the logic to do this in Javascript and then Swift, is there a best practice to only have to write the logic once and then call the same logic from both platforms?
Would cloud functions be the best way to achieve this? Could I write one cloud function in say Go, and then call this cloud function from both the iOS app in switft and ReactJS app in javascript? Is this best practice?
Using Cloud Functions to increase the amount of shared code is indeed a common use-case. A fairly regular pattern is to use Cloud Functions for more complex writes, where the client merely calls a single function, which then contains the more complex code. I'd still keep simpler write operations in the application code itself, but that is a matter of preference.
Note that if the duplicated code is a fan-out operation, you can also have the client write the primary document to the database itself, and then have that trigger a Cloud Function to perform the fan-out. That way the client still gets the benefits of writing through the SDK (e.g. it works offline), but some of the code is on the server and thus reused between clients.
I also see many developers creating Cloud Functions to join all the data they need. So that way the client can do just one call to get data from multiple collections. I'm not a big fan of that myself however, because you lose the offline and realtime capabilities of the Cloud Firestore SDKs that way.
I was done one small web application using ReactJS. It's easy to maintain and understandable. Now I learned Redux and plan to implement on it.
Its need some more stuff and extra things to do (To create store, Reducers etc.). I personally thought without redux the react is fine and easy to understand and maintain the states. Then why we need extra stuff (Redux)?
Reasons to use Redux:
Same piece of application state needs to be mapped to multiple
container components.
A good example of this is session state. When the app first loads, often information about the user needs to be shared with various components in the titlebar and each page. It’s likely these components don’t have any direct relationship so Redux provides a convenient way to share state.
Global strong textcomponents that can be accessed from anywhere.
It’s common to have components that live for the life of the application (for a single-page app this is every time the entry point is reloaded) that do things like show notifications, snackbars, tooltips, modals, interactive tutorials, etc. With Redux, you can create actions that dispatch commands to these components so, for example, if the code makes a asynchronous request to the backend it can dispatch a show snackbar action if the request fails. Without Redux, you would need some other event system or have to instantiate the snackbar component every time it gets used.
Too many props are being passed through multiple hierarchies of
components.
If a higher-level component is provided with a dozen props and uses only two of them, and the rest are passed down to a lower-level component, then consider refactoring with Redux. This scenario happens a lot with wrapper components that just provide layout styles, but don’t require a lot of data or configuration. It’s more practical to side-chain Redux directly into a lower-level component in this case.
State management using setState is bloating the component.
This is pretty subjective, but components that are over several hundred lines of code start to become harder to reason and maintain. Separating out the state management into a reducer breaks up the code and makes it more readable.
Caching page state.
When the user does some stuff to a page, then goes to another page and comes back, the expectation usually is to have the page in the same state. Some of this can be addressed by saving the page state in the backend and recalling it on page load. But, often things like search input values and expanded/collapsed accordions are just overkill to store in the backend. Since reducers typically initialize and live throughout the session, they can cache the page state so things remain the same.
Managing the state can be complex. Although react provides us with the state property but passing the state from component A to component B can be quite complex when the application grows. Here is a simple example which shows why do we need redux.
Consider an application with two functionalities "Users" and "Products".
Users have authentication implemented where they can sign-up and sign-in and the users can view the dashboard only when they are authenticated.
The other functionality "Products" also require user authentication information because the "Cart" operations will be accessible when the user is authenticated/signed-in. To get user authentication information at this part will require alot of state/props passing from "Users" component to a different section of the application "Products".
This is when Redux comes in picture, it provides a central store (stores entire application state) which is then available to the entire application.
TL;DR: Because you've done "one small web application". Not all web applications are small.
The most trivial examples of why you might need it include:
Sometimes unrelated components need to share state.
Sometimes state needs to be updated by things other than components.
Is it always necessary? Absolutely not. But breaking up state handling may confer advantages to non-small web applications, or complex interactions.
If all you have is a simple hierarchy of components, and things very low in that hierarchy never need to modify state that higher-level components need, then it brings in complexity that might not be necessary.
(Although even in those cases, it may be helpful; as always, "it depends".)
If you're building a house, you probably don't need a jackhammer even if you've learned how to use it.
You don't need Redux if your application's state is easy to manage without it.
As said in redux motivation page:
As the requirements for JavaScript single-page applications have
become increasingly complicated, our code must manage more state than
ever before. This state can include server responses and cached data,
as well as locally created data that has not yet been persisted to the
server. UI state is also increasing in complexity, as we need to
manage active routes, selected tabs, spinners, pagination controls,
and so on.
Managing this ever-changing state is hard. If a model can update
another model, then a view can update a model, which updates another
model, and this, in turn, might cause another view to update. At some
point, you no longer understand what happens in your app as you have
lost control over the when, why, and how of its state. When a system
is opaque and non-deterministic, it's hard to reproduce bugs or add
new features.
As if this wasn't bad enough, consider the new requirements becoming
common in front-end product development. As developers, we are
expected to handle optimistic updates, server-side rendering, fetching
data before performing route transitions, and so on. We find ourselves
trying to manage a complexity that we have never had to deal with
before, and we inevitably ask the question: is it time to give up? The
answer is no.
This complexity is difficult to handle as we're mixing two concepts
that are very hard for the human mind to reason about: mutation and
asynchronicity. I call them Mentos and Coke. Both can be great in
separation, but together they create a mess. Libraries like React
attempt to solve this problem in the view layer by removing both
asynchrony and direct DOM manipulation. However, managing the state of
your data is left up to you. This is where Redux enters.
Following in the steps of Flux, CQRS, and Event Sourcing, Redux
attempts to make state mutations predictable by imposing certain
restrictions on how and when updates can happen. These restrictions are reflected in the three principles of Redux.
But there are many cases where you won't need redux, it's important to understand what it does, and why you would need it.
I personally didn't use Redux in any of project I started over the last couple of year or so. I don't expect to use it in future either. Here's why.
Redux was revolutionary when it appeared in 2015. It brought two big ideas to React:
It combined action-based model of Flux with a concept of Reducer (It is in its name: "Red" "ux" = "Red"ucer + Fl"ux"). That Action - Reducer pattern instantly gained traction among React programmers.
It solved an application-wide state. Let's say we had certain data that we wanted to make available throughout the app. Before Redux the only reliable way to do that was to pass that data through props to child components... and then to their child components, and so on. Redux changed that. It allowed pieces of data to transcend the entire component hierarchy of an application without passing that data through props from one component to another. It also provided a convenient way to access and manipulate that application state from anywhere in the application.
Redux used a context API under the hood, which at the time was intended for React internal use only and was cumbersome to use.
Fast forward to 2019. A lot has changed. We now have hooks and the stable public context API which is ready for the prime time. An action - reducer pattern is now readily available via useReducer hook. We don't need Redux for that any more.
The modern React context API is simpler, more efficient than before and comes with hooks support. In most cases, wrapping your application state in a context is all you need to access it anywhere in your app.
So what about Redux?
My point of view that in a vast majority of cases you don't need Redux any more. Contexts and hooks get the job done most of the time. If you still think that contexts are not very friendly you may have a look at unstated-next library which is just a thin wrapper on top of the context API. That whole library is just 200 bytes!
However, plugging Redux into your project may be warranted if:
you want to take advantage of Redux middlewares such as redux-thunk
or you love Redux developer tools with their time-travelling ability.
In that case, make sure you know what you are doing. Redux magic comes with a price.
Redux is a complicated beast. It will bring a lot of complexity into your app. Some of that complexity is obvious while many other unobvious gotchas are hidden and waiting for you to trip on it. Think twice if you want to deal with that. Even then it is worth checking out alternatives such as MobX or react-sweet-state.
origin: You may not need redux
React ships with all the features you need to handle your state without a single additional library. Most of your application's states should not be global as they live just fine in a useState or useReducer or custom hook next to your components.
So before you dive into the world of advanced state management (e.g. Redux), consider using the tools React ships with out of the box.
If you are interested in learning a bit more about this, I'd recommend this article by Andy Fernandez: https://www.scalablepath.com/react/context-api-vs-redux
What is a good pattern for establishing a user session (including signup or login) in a Javascript/HTML5 app?
Specifically, I'm wondering how to delay displaying the main interface and initialising features until the async login is completed.
My app uses requirejs for modules, Parse for the backend (which is a NoSQL interface based on Backbone and MongoDB iirc). The main interface is currently simply hidden until app init completes and then made visible via CSS.
I am looking for a proper pattern to do this; the specifics of which libraries I'm using is only given for a little context. I suppose this is a basic Javascript question, but I can find it confusing to know how to wait for async calls. While I understand Promises, I am not sure for instance how to apply them to delaying initialising of separate modules...