-
Notifications
You must be signed in to change notification settings - Fork 16
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
Different objects with the same arguments #30
Comments
That's a feature. You are returning a reference to an input value, declaring that you need that object, and thus it would be added to a dependencies list. How to "fix"const aFunction = (state) => ({...state}); return a copy of the object. Like "I dont need |
But the main idea of memoization - storing the results of function call and return them with a same input values. |
Not exactly const obj = {
a: 1,
};
const result = useMemo(() => obj, []); // eslint: Hey, missing dependency
const result = useMemo(() => obj, [obj]); // eslint: ok
const result = useMemo(() => obj, [obj.a]); // eslint: ok memoizestate creates dependenct list in runtime useMemo(() => obj.a, [obj.a]) === memoizestate( state => state.a);
useMemo(() => obj, [obj]) === memoizestate( state => state); While with
Once again - let's check your example const aFunction = (state) =>({n: 42, data: state});
const memoFunc = memoize(aFunction);
// why it is working that way
const result1 = memoFunc({a: 1, b: 2}); // {n: 42, data:state}
const result2 = memoFunc({a: 1, b: 2}); // {n: 42, data:state}
// but here it would be ok?
const result1 = memoFunc(5); // {n: 42, data:5}
const result2 = memoFunc(6); // {n: 42, data:6}
|
No. According to the description of your library the object should be treated as the same. const aFunction = (state) => Math.random();
const memoFunc = memoize(aFunction);
const firstObject = {a: 1, b: 2};
const secondObject = {a: 1, b: 2};
const result1 = memoFunc(firstObject);
const result2 = memoFunc(secondObject);
console.log(Object.is(result1, result2))
// if the result is stored than the firstObject
// and the secondObject are the same object, right? Your problem is that for one case the objects are considered the same, and for the second they are different. |
You don't get the point - the object should be treated as the same until they are become a part of a result. That's working ok if the original state is immutable - there would be no "unexpected" new objects.
I could make this behaviour configurable - that's a one line fix - if you need this behavior, but I would have to ask you - what do you actually need. To be more concrete - on data return |
Can you give examples, how I can get "unexpected" new objects if I will be receive same object in a |
Structural sharing which is base layer for immutable structures means that if object updated - it is updated, and if you are passing a new object - that's a new object. But not always: const map = new Map();
const key1 = {a:1};
map.set(key1, 1);
const aFunction = (state) => state;
const memoFunc = memoize(aFunction);
const memoKey1 = memoFunc(key1);
expect(map.get(memoKey1)).toBe(1);
const key2 = {a:1}; // the same shape!
map.set(key2, 2);
const memoKey2 = memoFunc(key2);
expect(map.get(memoKey2)).toBe(2); // it is expected more if it - if you are not assessing any properly it yet again will think that you need "all of it" const aFunction = (state) => ({ x: state.a }); // would update ONLY when .a updated
const aFunction = (state) => ({ x: state.a, state }); // when .a, AND state updated
const aFunction = (state) => ({ x: 42, state }); // only state
const aFunction = (state) => (state); // only state So, let's start everything from the beginning - what is the case you are trying to solve? I've written 4 memoization libraries, and might be you need "not this one". |
And I am confused by the logic of working with objects in arguments. const aFunction = (state) => Math.random()
const memoFunc = memoize(aFunction);
const result1 = memoFunc({a: 1, b: 2});
const result2 = memoFunc({});
console.log(Object.is(result1, result2)) // true?..
const aFunction = (state) => Math.random()
const memoFunc = memoize(aFunction);
const result1 = memoFunc({a: 1, b: 2});
const result2 = memoFunc(1);
console.log(Object.is(result1, result2)) // false?.. |
I am not sure I have tests for |
I have noticed a regularity: if you try to return in the function the object which is an argument of that function, than each time a new object returns (although the argument hasn't changed regarding the library's work).
Even if the object is inside another object:
Is it bug or a feature?
The text was updated successfully, but these errors were encountered: