Reputation: 4142
I am using React and every time something changes it renders the whole component. Although I have a smallest possible component, but it runs a heavy function. I don't want this function to run on every render if its parameters has not changed. Something like React.memo
(basically don't re-render a component if its props have not changed). Is there an equivalent of React.memo
for static JavaScript functions?
NOTE: I don't want to pull in a library such as reselect
. There has to be a better way!
Edit: I feel like I was not very clear about what I was looking for. Let me ask this with an example,
Every time I click on +
or -
, it runs the pleaseMemoizeThisFunction
function, even though its parameter has not changed. How can I have this function only runs when any of its parameters change.
Upvotes: 1
Views: 2147
Reputation: 12677
This is a simple memoization implementation that checks wether the function is called with the same arguments as the last time, and only recalculates the result if they differ.
Seing in your sandbox that you use Typescript, I've added the Types to this function.
function memo<A extends any[], R>(fn:(...args:A) => R) {
let value:R,
before: A = {length:NaN} as any;
const sameAsBefore = (v:A[number], i:number) => v === before[i];
function memoized (...args:A):R {
if (args.length !== before.length || !args.every(sameAsBefore)) {
before = args;
value = fn.apply(this, args);
}
return value;
}
}
usage:
const pleaseMemoizeThisFunction = memo((a: string, b: string): string => {
console.count("function run: ");
// it will do some heavy stuff here
return `I am done with ${a} and ${b}`;
});
or like this.someMethod = memo(this.someMethod);
Upvotes: 0
Reputation: 1104
Use the useMemo hook around your functions and it will not run unless the params have changed. https://reactjs.org/docs/hooks-reference.html#usememo
const computed = useMemo(() => calculateExpensive(param1, param2), [param1, param2]);
Upvotes: 1