facebookexperimental/Recoil

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

Aperta

#1416 aperta il 13 nov 2021

 (31 commenti) (18 reazioni) (0 assegnatari)JavaScript (1151 fork)batch import
enhancementhelp wantedperformance

Metriche repository

Star
 (19.428 stelle)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

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.

Guida contributor