Recoil: Conditional useRecoilValue usage

Created on 21 May 2020  路  5Comments  路  Source: facebookexperimental/Recoil

How can I conditionally observe recoil state changes? I don't see that this is currently possible.
This is also not easy to do in MobX but it's possible.

I'd like to be able to pass a falsy value to useRecoilValue

isObserving = false;
const names = useRecoilValue(isObserving  && namesState);

See my MobX question: https://github.com/mobxjs/mobx-react/issues/864

enhancement

Most helpful comment

Internally there is another hook we use for conditional access:

function MyComponent() {
  const {getRecoilValue} = useRecoilInterface_UNSTABLE();
  ...
  const names = isObserving ? getRecoilValue(namesState) : null;
  ...
}

This allows conditional lookups, getting values in loops, after components short-circuit returns, &c. We're not super keen on the interface, though, it is unstable and will change. I'm hoping to come up with a safer/cleaner approach to publish.

All 5 comments

I guess I could use this approach?
const names = useRecoilValue(noopState);

Hi @AjaxSolutions.

I guess I could use this approach?
const names = useRecoilValue(noopState);

Yep that's the way. In Recoil/utils there is a useful helper for this pattern constSelector https://github.com/facebookexperimental/Recoil/blob/c38012d92a292a4a867163cf7b14cfb3debddf01/src/recoil_values/Recoil_const.js#L30-L32

Can use it like this:

const name = useRecoilValue(condition ? nameSelector : constSelector('Mary'));

Internally there is another hook we use for conditional access:

function MyComponent() {
  const {getRecoilValue} = useRecoilInterface_UNSTABLE();
  ...
  const names = isObserving ? getRecoilValue(namesState) : null;
  ...
}

This allows conditional lookups, getting values in loops, after components short-circuit returns, &c. We're not super keen on the interface, though, it is unstable and will change. I'm hoping to come up with a safer/cleaner approach to publish.

What's the current best practice to achieve the above? useRecoilInterface_UNSTABLE seems to be deprecated.

An option for conditional Recoil usage in a component:

function MyComponent() {
  const names = useRecoilValue(isObserving ? namesState : constSelector(null));
  ...
}

Or wrap in a selector:

const namesWhenObservingState = selectorFamily({
  key: 'NamesWhenObserving',
  get: isObserving => ({get}) => isObserving ? get(namesState) : null,
});

function MyComponent() {
  const names = useRecoilValue(namesWhenObserving(isObserving));
  ...
}
Was this page helpful?
0 / 5 - 0 ratings