Closed Nishchit14 closed 3 years ago
It isn't possible to access them outside of React as stated in #5. But you can do something like this to sync them: https://recoiljs.org/docs/guides/asynchronous-state-sync
I use this method to sync my state to leveldown DB in my electron application.
You could hack it
function MyCmp () {
const setValue = window.setValue = useSetRecoilState(someState)
}
function somewhereElse () {
window.setValue(123)
}
My team uses an empty component to capture and expose a getLoadable()
and set()
function. This only works if you have exactly one <RecoilRoot>
though:
import React from 'react';
import {
atom, AtomOptions, Loadable, RecoilState, RecoilValue, selector, Snapshot, useRecoilCallback,
useRecoilSnapshot
} from 'recoil';
// internal variables to hold the relevant recoil objects
let __snapshot: Snapshot = null as any;
let __set: <T>(
recoilVal: RecoilState<T>,
valOrUpdater: ((currVal: T) => T) | T
) => void = null as any;
// expose a function to set recoil state
export function RecoilSet<T>(
recoilVal: RecoilState<T>,
valOrUpdater: ((currVal: T) => T) | T
) {
__set(recoilVal, valOrUpdater);
}
// expose a function to get recoil state
export function RecoilGetLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T> {
return __snapshot.getLoadable(recoilValue);
}
// This component captures a snapshot to expose a get function, and a callback to expose a set function
export function RecoilUtilsComponent() {
__snapshot = useRecoilSnapshot();
useRecoilCallback(({ set }) => {
__set = set;
return async () => {};
})();
return <></>;
}
And this is our react root:
export default function Startup() {
return (
<RecoilRoot>
{/* this component is empty and it's only purpose is to sync external state with Recoil */}
<RecoilUtilsComponent />
<HistoryRecoilSync />
<MediaQueryRecoilSync />
<Initialize>
<AppHost />
</Initialize>
</RecoilRoot>
);
}
It's handy when we want to set some auth data as part of authentication/login flow.
I'm hopeful that this API #380 could help with this use case.
Updated documentation for syncing Recoil state with external storage in #680
Recently I came across the use case like a pure js file
Realtime.service.js
is making a connection with the WebSocket server and streaming realtime data to UI (need to feed multiple React's components with a chunk of data coming from realtime WS).Now if Recoil's atom state can be changed directly from
Realtime.service.js
(which is not a React component but js service) with realtime steam then all the components connected with the relative atoms will be updated on realtime data streaming.Is that a valid use case? Right now I've seen that Atom's state only get/set default-value by React's hook.
In redux it is possible, we can update the store from any js file (non-react env). and the
react-redux
bridge auto handles the changes to connected components. Now we're moving from Redux to Recoil, we're having this roadblock.