facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.6k stars 1.19k forks source link

CallbackInterface question #162

Closed AjaxSolutions closed 4 years ago

AjaxSolutions commented 4 years ago

Hi! Could someone explain the CallbackInterface and especially when getPromise, getLoadable and reset could be used? Thx.

type CallbackInterface = $ReadOnly<{
  getPromise: <T>(RecoilValue<T>) => Promise<T>,
  getLoadable: <T>(RecoilValue<T>) => Loadable<T>,
  set: <T>(RecoilState<T>, (T => T) | T) => void,
  reset: <T>(RecoilState<T>) => void,
}>;

https://github.com/facebookexperimental/Recoil/blob/1e6e077de77e35dadf28b1a452980f2cb76620a5/src/hooks/Recoil_Hooks.js#L513

acutmore commented 4 years ago

Hi @AjaxSolutions. As mentioned in the Recoil docs

where you need to read an atom's value without subscribing to the component

For example you may only need to read an Atom's value when a certain event happens. useRecoilCallback gives access to the value without causing the component to re-render every time the Atom/Selector is written to.

const items = atom({
  id: 'items',
  default: [],
});

function SubmitItems() {
  // We can read the value, but our component won't re-render when Recoil updates
  const getItems = useRecoilCallback(({getPromise}) => {
     return getPromise(items);
  }, []);

  const onClick = useCallback(async (clickEvent) => {
    clickEvent.stopPropagation();
    const items = await getItems();
    ServerAPI.submitItems(items);
  }, [getItems]);

  return <button onClick={onClick}>Submit</button>;
}

function ViewItems() {
  // This component will re-render when items changes
  const items = useRecoilValue(items);

  return items.map(item => <SomeComponent item={item} />);
}  

Another use case is when a component needs to access Atoms/Selectors dynamically. Example here: https://github.com/facebookexperimental/Recoil/issues/135#issuecomment-633145363

JimLiu commented 4 years ago

This is an example which used the CallbackInterface to load or set atoms dynamically: https://github.com/JimLiu/recoil-paint/blob/71309370aad6d39c7ce10c196354504098944900/src/recoil/hooks.js#L21