facebookexperimental/Recoil

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

開放

#1,416 建立於 2021年11月13日

 (31 則留言) (18 個反應) (0 位負責人)JavaScript (1,151 個分叉)batch import
enhancementhelp wantedperformance

倉庫指標

星標
 (19,428 顆星)
PR 合併指標
 (30 天內沒有已合併 PR)

描述

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.

貢獻者指南