-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into rework-useStorageValue
# Conflicts: # CHANGELOG.md # package.json
- Loading branch information
Showing
14 changed files
with
172 additions
and
15 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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import * as React from 'react'; | ||
import { useMemo } from 'react'; | ||
import { useRerender } from '../../useRerender/useRerender'; | ||
import { useDeepCompareMemo } from '../useDeepCompareMemo'; | ||
|
||
export const Example: React.FC = () => { | ||
const newOnEveryRender = { value: 'Foo' }; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
const unstable = useMemo(() => Math.floor(Math.random() * 10), [newOnEveryRender]); | ||
|
||
const stable = useDeepCompareMemo(() => Math.floor(Math.random() * 10), [newOnEveryRender]); | ||
|
||
const rerender = useRerender(); | ||
return ( | ||
<> | ||
<div style={{ display: 'flex', gap: '0.5rem' }}> | ||
<p>When you click this button:</p> | ||
<button onClick={rerender}>Rerender</button> | ||
<p>, you notice, that the useDeepCompareMemo value does not change at all,</p> | ||
</div> | ||
<p>even though its dependencies change on every render.</p> | ||
<br /> | ||
<p>useMemo: {unstable}</p> | ||
<p>useDeepCompareMemo: {stable}</p> | ||
</> | ||
); | ||
}; |
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,42 @@ | ||
import { Canvas, Meta, Story } from '@storybook/addon-docs/blocks' | ||
import { Example } from './example.stories' | ||
import { ImportPath } from '../../__docs__/ImportPath' | ||
|
||
<Meta title="Miscellaneous/useDeepCompareMemo" component={Example} /> | ||
|
||
# useDeepCompareMemo | ||
|
||
Like `useMemo` but uses `@react-hookz/deep-equal` comparator function to validate deep dependency changes. | ||
|
||
- SSR-friendly, meaning that the comparator won't be called on the server. | ||
- Uses yet fastest deep-comparator - [@react-hookz/deep-equal](https://github.com/react-hookz/deep-equal). | ||
|
||
#### Example | ||
|
||
<Canvas> | ||
<Story story={Example} /> | ||
</Canvas> | ||
|
||
## Reference | ||
|
||
```ts | ||
export function useDeepCompareMemo<T, Deps extends DependencyList>( | ||
factory: () => T, | ||
deps: Deps | ||
): T | ||
``` | ||
|
||
#### Importing | ||
|
||
<ImportPath /> | ||
|
||
#### Arguments | ||
|
||
- **factory** `() => T` - Function calculating the memoized value. Passed to the underlying `useMemo`. | ||
- **deps** `DependencyList` - List of all reactive values referenced by `factory`. Passed to the `deps` parameter of the underlying `useMemo`. | ||
|
||
#### Return | ||
|
||
Initially returns the result of calling `factory`. This value is memoized and returned on every | ||
render, until the dependencies change, determined by deep comparison, at which point `factory` will be called again and the resulting | ||
value will be memoized. |
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,31 @@ | ||
import { renderHook } from '@testing-library/react-hooks/dom'; | ||
import { useDeepCompareMemo } from '../useDeepCompareMemo'; | ||
|
||
describe('useDeepCompareMemo', () => { | ||
it('should be defined', () => { | ||
expect(useDeepCompareMemo).toBeDefined(); | ||
}); | ||
|
||
it('should render', () => { | ||
const { result } = renderHook(() => useDeepCompareMemo(() => {}, [])); | ||
expect(result.error).toBeUndefined(); | ||
}); | ||
|
||
it('should run only if dependencies change, defined by deep comparison', () => { | ||
const spy = jest.fn(); | ||
const { rerender } = renderHook(({ deps }) => useDeepCompareMemo(spy, deps), { | ||
initialProps: { deps: [{ foo: 'bar' }] }, | ||
}); | ||
|
||
expect(spy).toHaveBeenCalledTimes(1); | ||
|
||
rerender({ deps: [{ foo: 'bar' }] }); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
|
||
rerender({ deps: [{ foo: 'baz' }] }); | ||
expect(spy).toHaveBeenCalledTimes(2); | ||
|
||
rerender({ deps: [{ foo: 'baz' }] }); | ||
expect(spy).toHaveBeenCalledTimes(2); | ||
}); | ||
}); |
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,13 @@ | ||
import { renderHook } from '@testing-library/react-hooks/server'; | ||
import { useDeepCompareMemo } from '../..'; | ||
|
||
describe('useDeepCompareMemo', () => { | ||
it('should be defined', () => { | ||
expect(useDeepCompareMemo).toBeDefined(); | ||
}); | ||
|
||
it('should render', () => { | ||
const { result } = renderHook(() => useDeepCompareMemo(() => {}, [])); | ||
expect(result.error).toBeUndefined(); | ||
}); | ||
}); |
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,15 @@ | ||
import { DependencyList } from 'react'; | ||
import { isEqual } from '@react-hookz/deep-equal'; | ||
import { useCustomCompareMemo } from '../useCustomCompareMemo/useCustomCompareMemo'; | ||
|
||
/** | ||
* Like useMemo but validates dependency changes using deep equality check instead of reference check. | ||
* | ||
* @param factory Function calculating the value to be memoized. | ||
* @param deps The list of all reactive values referenced inside `factory`. | ||
* @returns Initially returns the result of calling `factory`. On subsequent renders, it will return | ||
* the same value, if dependencies haven't changed, or the result of calling `factory` again, if they have changed. | ||
*/ | ||
export function useDeepCompareMemo<T, Deps extends DependencyList>(factory: () => T, deps: Deps) { | ||
return useCustomCompareMemo(factory, deps, isEqual); | ||
} |
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