use-context-selector
use-context-selector copied to clipboard
[Question] Getting several context values at once?
Hi :wave:
First things first, thx a lot for this great work! :clap: I'm still discovering it, and maybe I'm going to ask a silly question but... is there any reason why useContextSelector examples were always using the same "one call, one value" pattern:
const v1 = useContextSelector((ctx) => ctx.v1)
const v2 = useContextSelector((ctx) => ctx.v2)
const v3 = useContextSelector((ctx) => ctx.v3)
...
...which seems quite verbose to me. Couldn't we simply use a single call such as:
const { v1, v2, v3 } = useContextSelector(({ v1, v2, v3 }) => ({ v1, v2, v3 }))
Thx a lot for your answer! :pray:
You can do that if you memoize the selector function. For example proxy-memoize does it for you.
import memoize from 'proxy-memoize';
const selector = memoize(({ v1, v2, v3 }) => ({ v1, v2, v3 }));
const Component = () => {
const { v1, v2, v3 } = useContextSelector(Ctx, selector);
// ...
};
Thx for this quick answer! I must be missing something but, why should I use memoization? Aren't both patterns eqs?
Because
const { v1, v2, v3 } = useContextSelector(({ v1, v2, v3 }) => ({ v1, v2, v3 }))
will trigger re-renders for any changes (like v4).
So, "one call, one value" pattern is the rule we follow. You might be interested in reading #19 discussion.
Hmmm... I'm not sure to perfectly understand why, but I'll be looking for some infos within the linked discussion :+1: Thx a lot @dai-shi !
Assuming you are not talking about custom equality function, const { v1, v2, v3 } = useContextSelector(({ v1, v2, v3 }) => ({ v1, v2, v3 })) is not technically easy.
It's not impossible though, and that's what react-tracked does.
const { v1, v2, v3 } = useTrackedState()
react-tracked uses use-context-selector under the hood. So, they do different jobs.
Ok thx a lot for all these informations, let's read (and learn) then :slightly_smiling_face:
Closing as answered.