-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Atom effect onSet() handler provides DefaultValue instead of new value when triggered by async default promise resolving. #1050
Comments
There were a couple fixes mentioned in the 0.3.0 release notes to |
Upon further investigation it appears to be something to do with the way we were handling our default values. Here is a cut down reproducer of how we handle it currently. import React from "react";
import { useRecoilValue } from "recoil";
import { atomFamily, selector } from "recoil";
const wait = (ms) => {
return new Promise((resolve, reject) => setTimeout(resolve, ms));
};
const defaultAsyncValue = async (param, type, defaultValue) => {
// this function usually checks if we have a value in local storage which is an async operations
// if we have no value it provides a default
await wait(2000);
return defaultValue;
};
const testEffect = () => async ({ setSelf, onSet }) => {
onSet(async (newValue) => {
console.log("newValue", newValue);
});
};
const testAtomFamily = atomFamily({
key: "testatomfamily",
default: (param) =>
selector({
key: "testatomfamily/Default",
get: () => defaultAsyncValue(param, "test", []),
}),
effects_UNSTABLE: (recipeId) => [testEffect()],
});
export function TestComponent() {
const testAtom = useRecoilValue(testAtomFamily(0));
return <></>;
} It seems that in 0.3.0 recoil doesn't wait for the DefaultAsyncValue to resolve and instead provides it's own default value an empty object. I'm unsure if this intended behavior, I did however find an example in the docs that uses a selector to provide a default value and this seems to resolve the issue, see below. const testAtomFamily = atomFamily({
key: "testatomfamily",
default: (param) =>
selector({
key: "testatomfamily/Default",
get: () => defaultAsyncValue(param, "test", []),
}),
effects_UNSTABLE: (recipeId) => [testEffect()],
}); Would you like me to update the title to better reflect the issue? |
Note that using a const testAtomFamily = atomFamily({
key: "testatomfamily",
default: selectorFamily({
key: "testatomfamily/Default",
get: (param) => () => defaultAsyncValue(param, "test", "TEST")
}),
effects_UNSTABLE: (recipeId) => [testEffect()],
}); For this case the I put in your test case reproducer here https://codesandbox.io/s/cool-forest-v2yyl?file=/src/App.js const testAtomFamily = atomFamily({
key: "testatomfamily",
default: (param) => defaultAsyncValue(param, "test", "TEST"),
effects_UNSTABLE: (recipeId) => [testEffect()],
}); For this case we expect the |
Summary: When an atom effect's `onSet()` handler is triggered due to having a default which is an async `Promise` that resolves the handler should be able to get the proper new value instead of a `DefaultValue` placeholder. This addresses customer-reported issue facebookexperimental#1050 Differential Revision: D28850148 fbshipit-source-id: ac9d946e9a14ab16b1165fb6890b2c8d059c155a
Summary: When an atom effect's `onSet()` handler is triggered due to having a default which is an async `Promise` that resolves the handler should be able to get the proper new value instead of a `DefaultValue` placeholder. This addresses customer-reported issue facebookexperimental#1050 Differential Revision: D28850148 fbshipit-source-id: 0f19d2179e7f3d522887550af32b87247f979f26
Duplicate of #738 |
Summary: When an atom effect's `onSet()` handler is triggered due to having a default which is an async `Promise` that resolves the handler should be able to get the proper new value instead of a `DefaultValue` placeholder. This addresses customer-reported issue #1050 Reviewed By: davidmccabe Differential Revision: D28850148 fbshipit-source-id: 323404beaac493756cd1a03592884959ccafecd5
Addressed with #1059 |
We use atom effects to sync up our recoil state with the local storage in our react native application. As of recoil 0.3.0 there seems to have been an undocumented change to behavior of the atom effects.
When our application first loads we retrieve our state from recoil using the following selector.
In recoil 0.3.0 using this selector also triggers the onSet part of our effects for these atomFamilies. See the code for the imagesAtomFamily and it's associated effect below.
When the onSet part of the effect is triggered it passes an empty DefaultValue object, what's even more odd is that this DefaultValue is not the same as the default we pass to the atomFamily, recipeData.images above is an empty array.
The text was updated successfully, but these errors were encountered: