Skip to content
This repository has been archived by the owner on Jan 1, 2025. It is now read-only.

Update for browser change in setTimeout() behavior #1943

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/recoil-relay/RecoilRelay_Environments.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @format
* @oncall recoil
*/

'use strict';

import type {Snapshot, StoreID} from 'Recoil';
Expand Down Expand Up @@ -65,16 +66,16 @@ function registerRelayEnvironment(
// production the environment registered should never change.
const pendingCleanup = cleanupHandlers.get(storeID)?.get(environmentKey);
if (pendingCleanup != null) {
clearTimeout(pendingCleanup);
window.clearTimeout(pendingCleanup);
cleanupHandlers.get(storeID)?.delete(environmentKey);
}
return () => {
const cleanupHandle = setTimeout(() => {
const cleanupHandle = window.setTimeout(() => {
environmentStore.get(storeID)?.delete(environmentKey);
}, 0);
const oldHandler = cleanupHandlers.get(storeID)?.get(environmentKey);
if (oldHandler != null) {
clearTimeout(oldHandler);
window.clearTimeout(oldHandler);
}
if (!cleanupHandlers.has(storeID)) {
cleanupHandlers.set(storeID, new Map());
Expand Down
21 changes: 6 additions & 15 deletions packages/recoil/core/Recoil_Snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ class Snapshot {
*/
autoRelease_INTERNAL(): void {
if (!isSSR) {
window.setTimeout(() => this._release(), 0);
// Use timeout of 10 to workaround Firefox issue: https://github.com/facebookexperimental/Recoil/issues/1936
window.setTimeout(() => this._release(), 10);
}
}

Expand Down Expand Up @@ -195,25 +196,22 @@ class Snapshot {
}

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
/* eslint-disable fb-www/extra-arrow-initializer */

getLoadable: <T>(RecoilValue<T>) => Loadable<T> = <T>(
recoilValue: RecoilValue<T>,
): Loadable<T> => {
this.checkRefCount_INTERNAL();
return getRecoilValueAsLoadable(this._store, recoilValue);
};

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
getPromise: <T>(RecoilValue<T>) => Promise<T> = <T>(
recoilValue: RecoilValue<T>,
): Promise<T> => {
this.checkRefCount_INTERNAL();
return this.getLoadable(recoilValue).toPromise();
};

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
getNodes_UNSTABLE: (
{
isModified?: boolean,
Expand Down Expand Up @@ -245,23 +243,20 @@ class Snapshot {

// Report the current status of a node.
// This peeks the current state and does not affect the snapshot state at all
// eslint-disable-next-line fb-www/extra-arrow-initializer
getInfo_UNSTABLE: <T>(RecoilValue<T>) => RecoilValueInfo<T> = <T>({
key,
}: RecoilValue<T>): RecoilValueInfo<T> => {
this.checkRefCount_INTERNAL();
return peekNodeInfo(this._store, this._store.getState().currentTree, key);
};

// eslint-disable-next-line fb-www/extra-arrow-initializer
map: ((MutableSnapshot) => void) => Snapshot = mapper => {
this.checkRefCount_INTERNAL();
const mutableSnapshot = new MutableSnapshot(this, batchUpdates);
mapper(mutableSnapshot); // if removing batchUpdates from `set` add it here
return mutableSnapshot;
};

// eslint-disable-next-line fb-www/extra-arrow-initializer
asyncMap: ((MutableSnapshot) => Promise<void>) => Promise<Snapshot> =
async mapper => {
this.checkRefCount_INTERNAL();
Expand All @@ -273,6 +268,8 @@ class Snapshot {
mutableSnapshot.autoRelease_INTERNAL();
return mutableSnapshot;
};

/* eslint-enable fb-www/extra-arrow-initializer */
}

function cloneStoreState(
Expand Down Expand Up @@ -379,8 +376,6 @@ class MutableSnapshot extends Snapshot {
this._batch = batch;
}

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
set: SetRecoilState = <T>(
recoilState: RecoilState<T>,
newValueOrUpdater: ValueOrUpdater<T>,
Expand All @@ -397,8 +392,6 @@ class MutableSnapshot extends Snapshot {
});
};

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
reset: ResetRecoilState = <T>(recoilState: RecoilState<T>) => {
this.checkRefCount_INTERNAL();
const store = this.getStore_INTERNAL();
Expand All @@ -409,8 +402,6 @@ class MutableSnapshot extends Snapshot {
});
};

// We want to allow the methods to be destructured and used as accessors
// eslint-disable-next-line fb-www/extra-arrow-initializer
setUnvalidatedAtomValues_DEPRECATED: (Map<NodeKey, mixed>) => void = (
values: Map<NodeKey, mixed>,
) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/recoil/hooks/Recoil_SnapshotHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ function useRecoilSnapshot(): Snapshot {
// re-render with the same state. The previous cleanup will then run and
// then the new effect will run. We don't want the snapshot to be released
// by that cleanup before the new effect has a chance to retain it again.
window.setTimeout(release, 0);
// Use timeout of 10 to workaround Firefox issue: https://github.com/facebookexperimental/Recoil/issues/1936
window.setTimeout(release, 10);
};
}, [snapshot]);

Expand Down