How to freeze time writing a story with Storybook? - reactjs

I have written a story with Storybook UI and deploying it with Chromatic. The issue is that my component takes into account the time now (I am using luxon, so I am using DateTime.now(), and it takes the diff with another date passed by props to show how many minutes have passed. Now, I am passing a fixed date to compare with, but the diff between now and that date makes it so that everytime code is pushed to Chromatic, it sees that as a change. How can I "freeze" DateTime.now() in Storybook so that this problem doesn't happen?

I just patch my Date.now function within the individual Story. You might want to patch other function depending upon how you're grabbing the date.
Date.now = () => new Date("2022-06-13T12:33:37.000Z");

Related

React.js aggregate state changes?

Webpack has an option that is called aggregateTimeout, this is explained as:
aggregate any other changes made during this time period into one rebuild
So the idea is, how can I bundle multiple changes within time period e.g. 1 second; to a single state update?
For example I have an editor in my react app, it updates the state each time the user types text on the editor, but I found that it makes the app a little laggy. So I want a timeout that ignores text inputs within, let's say 500ms, and it only updates after 500ms passed since the last time the user did text input.
How can I implement something like the case? Thanks.

What is the useState alternative for fast parallel, async state updates?

I'm trying to build a little calendar, where one can "mark" days by clicking on them.
Each click causes a request to the server to persist the change (set or unset a day).
It seems like useState can only keep up with so many changes at once, and due to the nature of reloading the component, i loose some of the fetch-requests happening as well.
When i understand the useState behavior correctly, each setDays will reload the whole Calendar, even if an instance still has a request running. The system is smart enought, so that a (limited) number of requests still manage to complete in the background and trigger their state update. However i have no control or guarantee over how many "make" it when clicking fast.
My real code has an additional state change, by marking/unmarking each day as "in flight" (via dayClassName) while the request is running, probably increasing the problem even more.
I'm a bit lost in what direction to go from here:
Should i try to limit the effect of a day change to a single day itself, avoiding to update the whole calendar with every click (need the result outside, though).
Or is a different system/strategy to manage the state, e.g. redux, the better choice here. For example to serialize the updates into one stream.
Update:
Here is a codesandbox with example: https://zpvy0.csb.app/
I tried to get as close to the real thing as possible, unfortunately i still can't reproduce the issue. It seems like react/useState is not the issue, as in the codesandbox it works reliable with 30+ requests triggered at once.
Update 2:
I have rewritten my code using the codesandbox version as base (re adding what other functionality/styling, etc was there). Now everything works perfectly.
Currently i have no idea what difference was causing it at the end.
If I'm understanding your issue correctly it sounds like the issue is that addDay and removeDay are called in quick succession and you are losing some state updates. You mention users clicking "to fast" so it may be the case that more than 1 state update is being enqueued. Since you are using plain updates if 2 updates are enqueued within the same render cycle the second update overwrites the first. If more get enqueued then each subsequent processed update overwrites the previous. Hopefully you get the idea here.
The resolution for this is to use functional state updates so each enqueued and processed update updates from the previous state, not the state the update was enqueued in. This means if multiple updates are enqueued in a render cycle each update/change is applied sequentially and the result aggregated state update is available for the next render cycle.
Functional Updates
If the new state is computed using the previous state, you can pass a
function to setState. The function will receive the previous value,
and return an updated value.
The previous state is an array and you are updating from that array when appending new day objects. It's a very minor tweak.
const addDay = async (day) => {
await makeRequest(day);
setDays(days => [...days, day]);
};
const removeDay = async (day) => {
await makeRequest(day);
setDays(days => days.filter((d) => d !== day));
};

Codename One action every N seconds

I'm working on my app developed with codename one. Now I need to perform an action every 10 seconds to update: Is there a sort of timer-thread which run always in background every N seconds?
If you need that action to happen off the EDT you can use java.util.Timer. If you want that action to happen on the EDT (e.g. you need to show something in the UI you) can use UITimer.
Notice that the latter is Form specific which might be an advantage or disadvantage based on the app requirements. So if you change a Form the UITimer won't be bound and you would need to create a new one.

Garbage collecting Redux/Flux stores

I'm in a project where we're currently using Redux for state management in our React-based Single page application, and we've run into an issue regarding when/how to clean out unused data from our stores (technically sub-state on or global Redux store).
For example we have a calendar "store" which looks
calendar = {
"2015-11-06": {
// Loads of data
},
... // More dates
}
Mostly we only care about a single date at the time, but there are cases where there are different components that needs different calendar date at the same time.
The question is: Is there some kind of strategy to "garbage collect" stores?
My initial thought is that components that need a specific calendar date will have to "reserve" that date and when it's unmounted, it'll remove its reservation. That way, when we reach some kind of size limit we can just remove all date that aren't reserved by any component.
It's a bit of a hassle though since it adds the need for components to handle "reservations" when fetching a date and when the component unmounts.
Is this a feasible strategy or is there a better alternative?
Sounds like a good use-case for a WeakSet or a WeakMap.
WeakMap holds references to its keys weakly, meaning that if there are
no other references to one of its keys, the object is subject to
garbage collection.
The key to all of this lies in a combination of this statement:
Mostly we only care about a single date at the time, but there are cases where there are different components that needs different calendar date at the same time.
...and how we think about state in an architecture like Flux/Redux.
There's nothing stopping you from restructuring your existing data store like so:
calendar = {
mainDate: {
date: "2015-11-06",
// Loads of data
}
}
Then, whenever you hit one of those special cases where you need more than one date, you issue an action that replaces the calendar state with something that looks like this:
calendar = {
mainDate: {
date: "2015-11-06",
// Loads of data
},
otherDate: {
date: "2016-02-29",
// Other data. Perhaps even less than the loads you'd have in mainDate
}
}
Somewhere along the line, your components will decide for themselves whether they need to look at mainDate or otherDate. (They may very well extract the appropriate one and then pass the contents down to their child components; you may want to introduce an abstraction layer here.)
And when the other component is done using the other date, it'll issue another action that generates:
calendar = {
mainDate: {
date: "2015-11-06",
// Loads of data
}
}
...thus automatically taking care of your garbage collection concern.
Obviously, there's a lot of implementation detail to be worked out here, but that's specific to your situation. The key concept is to contain all the state (and only the state) that you need to run the app at any given time, and use actions to make the transition from one state to another.

How to avoid React markup checksum warnings when rendering time

When leveraging isomorphic rendering for a React component that displays time, I occasionally run into an issue where the server renders time at point A, but by the time the client picks up as a SPA, the time from point A has changed to point B, and React throws a React attempted to reuse markup in a container but the checksum was invalid warning:
The occurrence of the error is obviously more pronounced as you display more granular time units like seconds, but it would be nice to be sure I won't run into this on minute, hour, day, etc. boundaries as well.
Is there a way to tell React on the client side, effectively, "It's OK, this little portion of the DOM here can differ from the server side"? Or perhaps another way I haven't thought of?
More Detail
I'm using the React-Intl FormattedRelative component to display an item's creation date in a friendly fashion. The item's creation date of course stays the same between client and server (and gets passed to the client in a serialized Flux store), but the server render and client render time difference is just long enough that the rendered HTML frequently — but not always — differs.
This has been fixed with React Intl v2. It adds a initialNow property to stabilize the rendered times.
A new feature has been added to <FormattedRelative> instances in React Intl v2, they now "tick" and stay up to date. Since time moves forward, it was confusing to have a prop named now, so it has been renamed to initialNow. Any <FormattedRelative> instances that use now should update to prop name to initialNow:
Usage:
<FormattedRelative value={date} initialNow={Date.now()}/>
You can also provide this on IntlProvider in which case all FormattedRelative instances are stabilized.
Note: The <IntlProvider> component also has a initialNow prop which can be assigned a value to stabilize the "now" reference time for all <FormattedRelative> instances. This is useful for universal/isomorphic apps to proper React checksums between the server and client initial render.
Usage:
<IntlProvider initialNow={Date.now()}>
<FormattedRelative value={date}/>
</IntlProvider>
Reference: https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#update-how-relative-times-are-formatted
Seeing as the data is going to change as soon as it renders client side, there is no point rendering that chunk server side.
So make a little component that renders this portion of information, but only by doing a force_update after mounting.
Before mount just put whatever you would like the user to see for the instant before rendering completes

Resources