Redux Dev Tools: Respond to state.json import in app UI - redux

I've been wondering about the import feature of the Redux Dev Tools. Correct my logic if it's faulty.
I'm working on a multi-step, form-heavy app UI, which serializes its state into Redux. It's inefficient to attempt to reproduce bugs by going through the app and filling/validating each field every time. I discovered the Redux Dev Tools (RDT) Export and Import features, and exported a state late into filling out and validating the form.
I relaunched the app fresh, navigated directly to the URL (it's in the dev environment, so no auth guards), and imported the state.json file.
Since the UI doesn't derive its state from Redux, but rather saves its state into Redux, the UI predictably, doesn't update when a state.json file is imported. This question is about responding to that singular, synchronous action of importing a state.json file.
I did some research, and found a package that RDT depends on called redux-devtools-instrument. It uses Redux internally, and has an action/reducer for IMPORT_STATE. Even when explicitly adding this package to my own dependencies, I'm not able to figure out how to subscribe to that event and rehydrate my UI. So, here are the two parts of my question:
Is the import feature of the RDT meant to work the way in which I'm describing?
How would you go about getting a "dumb" UI, which has no concept of Redux, or even state in general for that matter, to "listen" for that import state file action? I tried using RxJS, but didn't know what to subscribe to.

It sounds like the blocker here is that, as you said, "the UI doesn't derive its state from Redux, but rather saves its state into Redux". If that's the case, then importing an updated state into the Redux store is going to be pointless in terms of updating the UI.
In general, if you do your non-Redux-aware UI to respond to changes in the Redux store state or dispatched actions, you would need to use store.subscribe() or a Redux middleware to kick off changes to the rest of your UI after an action is dispatched.

Related

Electron - How to prevent locking of the UI

I have an app build with electron and on startup it does a large amount of API calls to setup the UI. This seems to render my UI unusable until it has all finished. I've read adding this code to the main process will have similar issues (lock up entire window). All the functions that make these API calls and save data to a vuex store return promises.
I've looked into creating child processes require('child_process').fork('/worker.js')); however I can't include my helper modules or classes from within those workers (SyntaxError: Unexpected token import).
What is the best way to do asynchronous work without blocking the UI, while still having access to my renderer classes and singletons?
This is the boilerplate I'm using if it helps https://github.com/SimulatedGREG/electron-vue/tree/master/template
Turns out I was calling vuex commit very fast which is a synchronous action and was causing the rest of the application to lock up as a result

React Native best practices for API handling

I've been working on the React Native platform this last couple of months and I need to implement a solid way to handle my API calls. At the moment I'm using redux to manage satate changes. Obviously the requestes must have a couple of retries if there is no network available, refresh oAuth tokens, etc.
Three solutions have ocurred to me:
Implement a "manager" class and handle all the logic in there. I like this one but I don't know if is possible to connect a non-component to redux since they dont have state.
Implement a couple of redux actions(request, onResponse, onError...) which should do the trick.
Create separated redux actions with their own fetchs to every call instead of having a centralized component.
What solution should I implement?
Another problem I've faced is that if a Network Error happens the promise is resolved even if I call the request again and I'm no longer able to make the behavior programmed in the caller method. Any workarounds?
Thank you for your time.
Redux has two powerful libraries that are designed to work with async API calls. These allow you to handle retries, errors, and slow API calls in the background of your app, simply by listening for a specific action.
Redux-thunk or Redux-saga are what you are probably going to want to use, so that you do not have to do all of the work of managing how components deal with API calls. Strongly recommend you check these out - there are quite a few tutorials out there that describe how to use these modules. Doing this by hand is not a good best practice IMO.
For api handling. you can have one single file which will have all function (export) and other settings needed so that you just have to import required methods.
You can use starter kit for react-native for basic structure for example: https://github.com/futurice/pepperoni-app-kit
it provides most of the things that we need for fresh project setup.
Follow the pattern mentioned in the below tutorial(youtube link below)
https://www.youtube.com/watch?v=9mlwjZL3Fmw
Everyone uses this pattern for API calls when following redux in react-native.
The tutorial is really good,its a great video.

Do I understand this MVC right?

I'm refactoring a large web app with another developer's help. In my mind, the backend is organized like so:
Symfony PHP: controller
PostgreSQL DB: model
As I understand it, the client-side browser is the 'view' of the server.
The frontend is additionally organized like this:
Redux.js: model + controller // this is all mildly simplified
React.js: view
Is it, therefore, conceptually correct to consider the client-side browser as the view of the server's state, and further, that the browser maintains its own state, controller, and view of the server-side data?
I'm a server-side "expert" (emphasize the quotes), while my helper is a front-end pro. We're deliberately trying to separate frontend and backend and restrict interaction to JSON payloads beyond the initial page load. If I'm looking at the global organization of the project right, it'll really help me organize our master codebase.
I don't think it's particularly helpful to think of the client-side app as just a view of the server-side state anymore.
The client-side is its own MVC application. Strictly, I don't think react-redux is actually MVC. It's considered an alternative to MVC. React is the View in MVC, but also a little bit of the Controller, and redux is an opinionated way of using the Model. You should read more here: http://redux.js.org/docs/introduction/Motivation.html
Relationship of the client-side M to the server-side M
Maybe another way of thinking about this is that the server has a 'model' and a part of the redux state-tree is actually kind of a view of that 'model' (like a list of todos derived from and kept in sync with a todo table on the server-side).
Parts of the redux state-tree could also have nothing to do with the server-side 'models' and could just be useful for storing client-side state (like the current url/route).
My firm belief is to not worry too much about the terminologies too much and stick to first principles. The server has state, the client-app has state. A part of the client-app's state is derived from and/or synced to the server-side state. The rest of the client-app's state helps generate the UI that the user sees. As the user interacts with the app, code is triggered that manipulates the state. Once you write a simple react-redux app, you'll see where all these pieces go!
Sounds about right.
The state of the application
React components maintain internal state. The state is updated via this.setState upon an event (e.g. click, mouse move, keyboard input, timeout, AJAX response, etc.). When this.setState is called, en entire re-render of the component is scheduled, after which, the component is then redrawn.
The cycle pretty much continues. You can think of React's state to work just like a traditional LAMP web app, that is, in an example web app, user submits a form, the page is updated with new content. Only that instead of you setting up the listeners, and imperatively telling react what data to pass in to this.setState, with a traditional LAMP app, you do so declaratively in the HTML declaration of the <form>, in the inputs that you define.
Albeit, the above React vs LAMP example is probably a bad analogy, because React does not directly work with the server. It's your responsibility on how to design your code to work with the server.
Communication with server
So, with LAMP, trivially, if you want user input to persist on the server, you simply record the input from a form POST request.
With react, there's an extra step on your end.
When a user triggers an event (click, mouse move, keyboard input, etc.), you first need to issue an AJAX request, which, of course, the server will act on the request (e.g. store form input).
In the (successful) response callback, you would then call this.setState to update what the server responded with. With a traditional LAMP app, you would get an entirely new web page rendered with the user's persisted data. With React, instead, you get back some piece of data (perhaps JSON or XML) which isn't the web page, but is used by your front-end application to determine what the page should look like.
Is it, therefore, conceptually correct to consider the client-side
browser as the view of the server's state, and further, that the
browser maintains its own state, controller, and view of the
server-side data?
Yes, it is completely correct.
In fact, you can think about your web app as an MVC that lives inside another MVC (the browser) that is then executed inside another MVC (the OS windowing system). Which communicates with another MVC across the wire (your backend app).
Now, swap MVC for "the implementation of a software design pattern", because there is no canonical definition of what MVC is. There are many variations, for example, MVC in the server is quite different from MVC in a client machine.
The server side approach is based on what is known as Java Model 2. This design shares the same philosophy as MVC and most of its components resemble it, so we all call it MVC. Which is not incorrect, although inexact too.
http://givan.se/mvc-past-present-and-future/#server-mvc
You can compare all of the documented patterns that belong to the MVC collection here:
http://mvc.givan.se/

Replaying actions in Redux

I'm building an library with Redux that involves using a timer. I have an action creator that dispatches a START_TIMER event and should also should also call start on a timer object. The code looks like this:
// thunk action creator
const startTimer = () => (dispatch, getState) => {
if (!getState().timer.isRunning)
externalTimerObject.start()
dispatch({
type: 'START_TIMER'
})
}
There are two issues I'm trying to solve:
If I want to log my actions to a database or localStorage so that I can replay them to get to a consistent app state then even if rootState.timer.isRunning is true, my timer object will not be running.
The conditional if (!getState().timer.isRunning) requires that I know where in the root state timer is mounted. Since I'm building this as a library, I can't assume that timer is always going to be mounted directly onto the root state.
If I want to log my actions to a database or localStorage so that I can replay them to get to a consistent app state then even if rootState.timer.isRunning is true, my timer object will not be running.
I think that this is actually correct by design. When you reproduce a recorded log, you want everything to happen exactly as it happened before in terms of the produced actions.
For example, rather than fire off the real AJAX requests from your computer, while replaying actions, you’ll probably want to replay the recorded AJAX responses that were dispatched during that user session in the past.
I think timer falls into the same category: from the Redux point of view, action history describes what happened “as a result” of side effects, and replaying the actions should be enough to get your app into the same state even if those side effects did not actually fire again.
The conditional if (!getState().timer.isRunning) requires that I know where in the root state timer is mounted. Since I'm building this as a library, I can't assume that timer is always going to be mounted directly onto the root state.
If you’re building a library, you also probably shouldn’t depend on the thunk middleware being available. It seems like you depend on it in your action creator. It is hard to say more without understanding your exact use case.

Shared Redux Different App stores.. how?

I'm in a bit of head scratcher here. I have two apps. They are separate tools. BUT, one of the tool 1, uses part of tool 2. HOW can tool 1 get at and into tool 2 Redux state? Is there a middleware that enables me to bind them somehow.
TOOL APP1 --- has its own redux store
TOOL APP2 --- has its own redux store
I need a behavior from APP2 for APP1. So, instead of "building" a new version, just import APP2's sub section and use that.... NOW, here is the rub. APP1 now needs to know how to set, and retrieve the states it stores in APP2 sub component....
Is there a methodology in place for redux to do this, or ?
Worse comes to worse, I guess I can store the APP2 sub component state in localStorage or redis etc.. and then I can hydrate APP1 with it.. but....
Not so difficult.
You can do it by providing shared Container components (means wrapped by calling connect() of react-redux), shared Reducers, shared Actions (with Action Creators), and shared Middlewares. Then, you use Container components, insert Reducers, and apply Middlewares in your main application.
This is a demo app contains shared self-contained components.
https://github.com/kuy/popover-profile
Timeline App: Online Demo
Message App: Online Demo
Please hover username in the pages. You will get popup profiles.
These two apps share a Popover Profile component, like Gmail's or SoundCloud's profile tooltip on mouseover names. No only sharing state, this component communicates with (fake) API server. This can be done by a shared Middleware using redux-saga.

Resources