In my application I have a selector that checks if the data it's fetching is stale. If it isn't stale, the selector returns the data; else it doesn't. It checks the staleness by comparing the current time (via new Date()) with the time that the data was loaded.
When trying to scrub back in forth in actions in the Redux dev tools, however, since the time is not part of the Redux store, the selector will call the data stale even if at the time of the action it wasn't.
So the core problem seems to be that Redux is no longer acting as a single source of truth—the clock time is now an external dependency. The goal, then, would be for the clock time when the selector is accessed to be a part of the Redux state, to properly allow for time travel debugging.
But what is the most elegant way to have an access of the Redux store dispatch a state transition? One way is to manually add an updateTime() dispatch every time you access the selector, but that requires remembering every time the selector is invoked to make that call, which I find to be less than ideal.
Another floated option was to keep track of the current time upon every state transition, but that doesn't help since it doesn't actually trigger an update upon time of access, but only upon the time that the state itself changed.
How do other people deal with this problem? I'm failing to find a nice solution around this. Thanks!
Related
I'm new to react and I want to build a Spotify clone which lets me control my playback. Therefore I'm fetching the API every second to get the current data.
So far everything works just fine but I'm asking myself what would be the best way to display the current data in the browser.
Right now I'm using a useState for the current data which rerenders my code including the DOM and displays the data every time I set the useState. As this happens every second I have my concern if this is performant.
Are there any best practices or concepts I can use? I was thinking about setting the current data via innerHTML as with that I could avoid rerendering my component every second.
Thanks for every answer!
In my React Native app, I have several state variables that get initialized to zero in the constructor, and then updated by the user. The problem is that when I'm running the app on an emulator, whenever I save my code, the emulator hot reloads, and the constructor gets run, thereby resetting all these state variables to zero. Is there a standard way to handle this? Or should I just actually reload every time this happens, and assume this won't be a problem when I'm running the app in real life?
Thats not something you can handle it. Bundler does everything. Sometimes it resets states sometimes does not. Always remaps all bundles and patch them through the DOM and it depends on your DOM tree.
It is my understanding that you are not supposed to change states in the render function cause that would cause and infinite re render or the component.
This makes perfect sense, but I find myself in a particular situation. I am building an offline application and I am using an offline storage system to retrieve data. Now, whenever a method is called to get certain data, cache is checked, if it is not expired the component will be able to access the data and therefore nothing happens, but if it is expired there is a call to the API, the data is updated and the interested components re-rendered.
These methods will change the state of the component the first time they are called because they are going to the API grabbing the new data and re-rendering, and then they will not change the state anymore because the data will already be in cache.
Now, I could call these methods in component will mount, and that is what I am doing now, but if I am forced to re call them, I need to unmount and remount the components. Is this the only possible way of doing this?
Thanks!
Well the first step is understanding that state management and rendering needs to be decoupled which you got already.
Now what you can do is consider your external state/cache element as an observable object (ie. I want to do something like observableObject.listen('change', onChangeHandler); you can use EventsEmitter from the events library). You do that listening on componentDidMount and clean up in componentWillUnmout. That onChangeHandler is very simple: this.setState({ value: observableObject.value }) which will trigger a component re-render which should be a pure function that outputs DOM nodes depending on props being passed and it's own state.
This means that your logic of checking if the cache is invalid is not on a per request of the value (inside rendering) but rather think of the object as self contained. It regularly checks if itself needs to notify its listeners that it changed. Since JS does not do parallel execution you don't have to deal with threads and synchronization. You know that at the point in time your render function executes it will have the latest value. If after rendering the logic that checks for cache executes and it sees that it needs to be updated it simply notifies as said earlier its listeners and that makes your component re-render because your onChangeHandler changed the state.
Hope I helped.
In short, I am wondering if it possible to make an Angular controller pick up where it left off after the page is refreshed.
To give more details, suppose I have a controller that is responsible for running timers on several DOM items on that page. I click start, timer runs until I stop it. Now, when the page is refreshed, the timer and all values are re-set to zero. How could I make them continue from where they were immediately before the refresh event? In fact, is there a way to account even for the time it took for the page to refresh?
Currently, Angular is doing the timing. Should I try to switch timing to Node side?
Any advice is appreciated.
I strongly recommend that you try to switch the timer values to Node's side. That's the only way you can get the timers really updated and synchronized with your server.
I do not encourage that you store the timer values on storage, you will never have a reliable data, since the user can easily modify it.
Since there is no persistence of state between page loads in javascript you would need to store the timer state. localStorage would be one option
Not clear if timer is working towards a fixed time or tracking elapsed time. Store wht works best to allow you to reactivate when service runs again
I'm implementing a JavaScript-based Vaadin component that will need to show and update a relatively large data set. I'm doing this by extending AbstractJavaScriptComponent.
I'm trying to keep the JS side as "dumb" as possible, delegating user interactions to the server using RPC, and which updates the shared state. Then the JS connector wrapper's onStateChange function is called with the new state, which causes the DOM to be updated accordingly.
I have 2 problems:
I don't want to transfer the whole data set each time a small part gets updated.
I don't want to entirely rebuild the UI each time either.
I can solve the second problem by keeping the previous state and comparing parts of it to find out what changed and only make the necessary DOM changes.
But that still leaves the first problem.
Do I have to stop using Vaadin's shared state mechanism and instead only use RPC for communicating the changes to the state?
Update:
I've been doing some testing, and it certainly appears that Vaadin's shared state mechanism is horrible in terms of efficiency:
Whenever the component calls getState() in order to update some property in the state object (or even without updating anything), the whole state object is transferred. The only way to avoid this, as far as I can see, is to not use the shared state mechanism and instead use RPC calls to communicate specific state changes to client.
There are some issues with the RPC approach that will need to be resolved, for example: if you change a value multiple times within a single request/response cycle, you don't want to make the RPC call multiple times. Instead, you want only the last value to be sent just like the shared state mechanism only sends the final state in the response. You can keep dirty flags for each part of the state that you want to send separately (or just keep a copy of the previous state and compare), but then you need to somehow trigger the RPC call at the end of the request handling. How can this be done?
Any ideas on this are welcome!
Update 2:
Vaadin 8 fixes the root issue: it sends only the changed state properties. Also, it doesn't call onStateChange() on the JS connector anymore when only doing an RPC call (and not changing any state).
OP is correct in stating that shared state synchronisation is inefficient for AbstractJavaScriptComponent-based components. The entire state object is serialised and made available to the Javascript connector's onStateChange method whenever the connector is marked as dirty. Other non-javascript components handle state updates more intelligently by only sending changes. The exact place in the code where this happens is line 97 in com.vaadin.server.LegacyCommunicationManager.java
boolean supportsDiffState = !JavaScriptConnectorState.class
.isAssignableFrom(stateType);
I'm not sure why state update is handled differently for AbstractJavaScriptComponent-based components. Maybe it's to simplify the javascript connector and remove the need to assemble a complete state object from deltas. It would be great if this could be addressed in a future version.
As you suggest, you could dispense with JavaScriptComponentState completely and rely on server->client RPC for updates. Keep dirty flags in you server-side component or compare old state and new state by any mechanism you want.
To coalesce the changes and send only one RPC call for each change, you could override beforeClientResponse(boolean initial) in your server-side component. This is called just before sending a response to the client and is your chance to add a set of RPC calls to update the client-side component.
Alternatively, you could override encodeState where you have free-reign to send exactly whatever JSON you like to the client. You could choose to add a list of changes to the base JSON object returned by super.encodeSate. Your javascript connector could interpret as appropriate in its onStateChange method.
Edited to add: calling getState() in your server-side component will mark the connector as dirty. If you want to get state without marking it as dirty then use getState(false) instead.
Following our discussion about this, I've created a drop-in replacement for AbstractJavaScriptComponent that transmits state deltas and includes some extra enhancements. It's in the very early stages but should be useful.
https://github.com/emuanalytics/vaadin-enhancedjavascript
The solution is deceptively simple: basically re-enabling state difference calculation by bypassing this line of code in com.vaadin.server.LegacyCommunicationManager.java:
boolean supportsDiffState = !JavaScriptConnectorState.class
.isAssignableFrom(stateType);
The implementation of the solution is complicated by the fact that the Vaadin classes are not easily extended so I've had to copy and re-implement 6 classes.
Vaadin's shared state works exactly like you want out of the box: when a component is added to the DOM first time, the whole shared state is transferred from server to client, so that it's possible to display the component. After that, only changes are transferred. For example, one changes the caption of a visible component by calling component.setCaption("new caption"), Vaadin only transfers that new caption text to client and "merges" that to the client-side shared state instance of the component.