-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: have shouldRecompute
instead of custom equality function
#39
Comments
Very interesting! Worth thinking about more for sure |
@alamothe what if we passed the index in as the third argument to the |
- type EqualityFn = (a: mixed, b: mixed) => boolean;
+ type EqualityFn = (a: mixed, b: mixed, index: number) => boolean; |
this seems like a reasonable path forward 👍 |
Thanks! Would love to use the library for this use case as well 🙂 It serves really well for memoizing things based on props as recommended by React |
Would an index be a reasonable path forward for you? |
In my opinion, it could improve the general case a bit (i.e. check for index instead of type), but it doesn't solve the use case I mentioned (where previous, cached result is also necessary to make a decision whether it is still valid). |
Closed by #42 |
I like the latest API but still doesn't work for my case. How about just pass |
I also need something like Reduced test case: import assert from 'assert';
import memoizeOne from 'memoize-one';
type User = { age: number; name?: string };
const getAges = (user1: User, user2: User) => [user1.age, user2.age];
const getAgesMemoized = memoizeOne(getAges);
const user1: User = { age: 10 };
const user1b: User = { ...user1, name: 'bob' };
const user2: User = { age: 20 };
// No error ✅
assert(getAgesMemoized(user1, user2) === getAgesMemoized(user1, user2));
// Error ❌
// Arrays do not have the same references, but their contents have not changed.
assert(getAgesMemoized(user1, user2) === getAgesMemoized(user1b, user2)); /cc @alexreardon Do you think we reconsider adding something like |
As a workaround incase it helps others, I ended up creating a helper to achieve this: import { identity } from 'fp-ts/lib/function';
import memoizeOne from 'memoize-one';
import { pipe } from 'pipe-ts';
// https://github.com/alexreardon/memoize-one/issues/39#issuecomment-609927050
export const memoizeOneByResult = <A extends unknown[], R>(
fn: (...args: A) => R,
isResultEqual: (a: R, b: R) => boolean,
) => pipe(fn, memoizeOne(identity, isResultEqual)); |
I would like to be able to provide a function:
instead of custom equality function. In my case, whether the result should be recomputed depends on the previous result.
Use case:
I am building a calendar with monthly view. For input data (events etc.) and given date, I filter events and compute begin and end, which are first and last timestamp for that month. In
shouldRecompute
, I would like just to check if new date is between these two values. Alternative is to have a custom equality which would compare months of previous and new date argument, but this is pretty costly (in general they are unix timestamps).In general, my opinion is that
shouldRecompute
is better than custom equality even for general case. Most of the time, arguments have different types, so custom equality ends up being a branchyif
statement checking for types of arguments and performing duty.With
shouldRecompute
, it would be possible to test all arguments at once, which is much easier to reason about.E.g. before:
after:
The text was updated successfully, but these errors were encountered: