facebookexperimental/Recoil

[Feature request] Customizable control over when a selector triggers re-render

Open

#1 416 ouverte le 13 nov. 2021

Voir sur GitHub
 (31 commentaires) (18 réactions) (0 assignés)JavaScript (1 151 forks)batch import
enhancementhelp wantedperformance

Métriques du dépôt

Stars
 (19 428 stars)
Métriques de merge PR
 (Aucune PR mergée en 30 j)

Description

Proposal

I would like to be able to specify a custom function for cache comparison on an atom/selector so I can tweak the behaviour. Let's say we have a configurable algorithm with multiple steps, and some options that pertain to a step each.

const algorithmOptions = atom({
	key: 'algorithmOptions',
	default: {
		featureA: true,
		featureB: true,
		featureC: false,
	},
});

Now, only step 2 options are relevant for the step 2 of the algorithm, so we make a selector to fetch only that

const step2Options = selector({
	key: 'step2Options',
	get: ({get}) => {
		const allOptions = get(algorithmOptions);

		return {
			allOptions.featureB,
			allOptions.featureC,
		};
	},
	// overwrite cache comparison, so we don't trigger unnecessary rerenders by modifying algorithmOptions.featureA
	cacheCompare: (old, new) => old.featureB=== new.featureB && old.featureC === new.featureC,
})

That way, we don't trigger an unnecessary rerender when doing setOptions({ ...options, featureA: !options.featureA }).

Motivation

This can currently be done using an intermediate selector, but it's a lot of boiler plate and makes the code look clunky. Here's a code sandbox showing the intermediate selector pattern: https://codesandbox.io/s/busy-cherry-u4rx6?file=/src/App.tsx

The real life use cases for this are when you get a state object from a backend, which you want to split out into multiple parts, or if you have a form for configuration of something, and you want to save the state of the form as is.

Guide contributeur