Comments (10)
There is a useTransactionObservation_UNSTABLE
hook you can use to subscribe to state changes for managing persistence. There is also a persistence_UNSTABLE
option for atoms to add metadata, such as a validator function. It's listed as _UNSTABLE
as we're still finalizing the API, but we use this internally. We're working now to clean up this API and publish an example persistence library.
from recoil.
@Qrysto @Joonpark13 - Yup, stay tuned for "Atom Effects" coming soon...
from recoil.
FWIW, I like the idea.
Recoil has allowed me to break down my state to neat, reusable parts. In a complex application, that's a real plus and the code is much cleaner than redux/context versions I've had before.
But there are plenty of occasions where the state logic (separate from the display logic) demands knock-on effects and it feels right to try to wrap those parts of the code in together.
from recoil.
I think a great way to handle it would be to have a type like EffectSubscriber<T>
where you would dispatch messages of type T
to it and it has the ability to parse the sent data and set atoms and perform effects as needed. It would let the subscriber be ignorant of how it gets messages which means it could even be sent new data from multiple sources (and be less fragile to code changes).
In addition, it would be awesome to have its own state as well. This would really enable a MVU pattern within recoil. So it would be something along the lines of giving it an initial state and like the set
field for selectors where it takes the object to perform operations {set: SetRecoilState, get: GetRecoilValue, reset: ResetRecoilState}
and the new message T
and then returns the new state and any effects to dispatch (like an array of void => void
).
Where it would look something like this:
const mySubscriber = effectAtom({
key: 'mySubscriber',
default: { someField: 1 },
update: ({get, set}, msg, state) => {
if (msg.tag == SomeType.SomeMsg) {
return { someField: msg.value + state.someField }, []
}
else {
return state, [() => console.log("hello!")]
}
}
});
Ideally modifying the state would be done inside the effect array as well to make the update function pure(er), but in either case I think this would be effective.
This is a well established pattern in Elm, F#, and other functional languages as a way for handling effects.
I don't know, but this idea of making the effects lazy might help with concurrent mode compatibility?
from recoil.
As Douglas said we have an API that you can use for this currently, albeit it's a bit half-baked and we're planning a much better and more flexible version soon. In the meantime, check out useTransactionObservation and the initializeState
prop of RecoilRoot (unlike what you have with default
there this doesn't depend on module evaluation timing.)
If you just want an effect to be triggered by changes to a specific atom, you can also have a component with useEffect
.
from recoil.
I think there still needs to be a way to subscribe to individual atoms instead of relying on only useTransactionObservation_UNSTABLE
, since one of the main points of using recoil instead of redux is to avoid triggering ALL unrelated subscribers at every single change in the app state.
from recoil.
Having looked at the new "Atom Effects", there still doesn't seem to be a simple way to alter the value of one atom when another's state changes. Perhaps you envisage selectors for that, but I've yet to see (or figure out) a way to make that work neatly if both states are atoms.
"Atom Effects" has setSelf/resetSelf, but what if I want to setOther/resetOther?
Is there/will there be a way to subscribe to one atom and then set another on change, without going the useEffect route (which just feels clunky)?
This my current approach, but I dislike the way it's separate from my main state code.
DimensionsAtom needs to be reset whenever listingAtom changes.
function StateManager() {
const listing = useRecoilValue(listingAtom);
const setDimensions = useSetRecoilState(dimensionsAtom);
useEffect(() => {
setDimensions({});
}, [listing]);
return null;
}
from recoil.
Contemplating adding some sort of onListen()
for an atom effect to listen to other atoms/selectors. But, trying to reason if it's really justified and doesn't encourage bad patterns.
from recoil.
Currently, this is how I have implemented a watcher facility for my form.
export const subscribeToFormFieldsSelector = selectorFamily<
FormFieldAtomType[],
string[] | undefined
>({
key: atomKeys.subscribeToFormFieldsSelector,
get: (fields = []) => ({ get }) => {
if (!Array.isArray(fields)) {
fields = [fields];
}
let fieldValues: FormFieldAtomType[] = [];
for (let field of fields) {
if (typeof field === "string" && field !== "") {
let fieldState = get(formFieldAtom(field));
fieldValues.push(fieldState);
}
}
return fieldValues;
},
});
from recoil.
Covered by atom effects
from recoil.
Related Issues (20)
- Under active maintenance? HOT 16
- How to avoid "Setting selectors within atomicUpdate is not supported" when using useRecoilTransaction__UNSTABLE
- RecoilLoadable contains Promise value will never change state from 'loading' to other states.
- RecoilURLSync has unnecessary encodeURIComponent for search serializer
- Testing custom hook with recoil atom inside
- There is a bug on your website HOT 1
- onSet is not triggered when using `useRecoilState` HOT 2
- If value is a NaN, it causes an infinity render HOT 1
- Nested RecoilRoot using initializeState has unexpected results
- `jotai-recoil-adapter`: a community project for making life easier when migrating from Recoil to Jotai HOT 1
- [Question]how to return extra info with async atom
- Android: Setting recoil state yields "ownKeys target is non-extensible but trap result keys differ from target keys"
- Feature request: Selector-like hook for components HOT 2
- Problems with Continuous Updates HOT 1
- Using RecoilRoot via npm HOT 2
- Recoil-Sync syncEffect Jest error
- can't use the search box to jump to destination on the official website
- recoil state getting reset after auth with different platforms HOT 1
- Japanese Translation
- getPromise() in atom effects does not resolve
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from recoil.