facebookexperimental/Recoil

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

オープン

#1,416 opened on 2021/11/13

 (31 件のコメント) (18 件のリアクション) (0 人の担当者)JavaScript (1,151 件のフォーク)batch import
enhancementhelp wantedperformance

Repository metrics

Stars
 (19,428 個のスター)
PR merge metrics
 (PR metrics pending)

説明

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.

コントリビューターガイド