-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor React object memoization using custom hook
**Why**: - More concise - Less error-prone in case of forgotten dependency key - May encourage memoization of objects when appropriate, by making it less tedious to accomplish changelog: Internal, Performance, Create helper utility for front-end object memoization
- Loading branch information
Showing
6 changed files
with
90 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
app/javascript/packages/react-hooks/use-object-memo.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
import useObjectMemo from './use-object-memo'; | ||
|
||
describe('useObjectMemo', () => { | ||
it('maintains reference over re-render for identical object values', () => { | ||
const { rerender, result } = renderHook(({ object }) => useObjectMemo(object), { | ||
initialProps: { object: { a: 1 } }, | ||
}); | ||
|
||
const { current: object1 } = result; | ||
|
||
rerender({ object: { a: 1 } }); | ||
|
||
const { current: object2 } = result; | ||
|
||
expect(object1).to.equal(object2); | ||
expect(object1).to.deep.equal({ a: 1 }); | ||
}); | ||
|
||
it('updates reference when re-rendering with new values', () => { | ||
const { rerender, result } = renderHook(({ object }) => useObjectMemo(object), { | ||
initialProps: { object: { a: 1 } }, | ||
}); | ||
|
||
const { current: object1 } = result; | ||
expect(object1).to.deep.equal({ a: 1 }); | ||
|
||
rerender({ object: { a: 2 } }); | ||
|
||
const { current: object2 } = result; | ||
expect(object2).to.deep.equal({ a: 2 }); | ||
|
||
expect(object1).to.not.equal(object2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { useMemo } from 'react'; | ||
|
||
/** | ||
* React hook which creates a memoized object whose reference changes when values of the object | ||
* changes. | ||
* | ||
* This can be useful in situations like object context values, since without memoization an object | ||
* context would trigger re-renders of all consumers on every update. | ||
* | ||
* Note that the keys of the object must remain the same for the lifecycle of the component for the | ||
* hook to work correctly. | ||
* | ||
* @param object Object to memoize. | ||
* | ||
* @return Memoized object. | ||
*/ | ||
const useObjectMemo = <T extends object>(object: T): T => | ||
useMemo(() => object, Object.values(object)); | ||
|
||
export default useObjectMemo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters