Skip to content

Commit

Permalink
Merge branch 'master' into rework-useStorageValue
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.md
#	package.json
  • Loading branch information
xobotyi committed Oct 24, 2022
2 parents e5b56a2 + 866ea58 commit b5b776e
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 15 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# [16.1.0](https://github.com/react-hookz/web/compare/v16.0.1...v16.1.0) (2022-10-23)


### Features

* **useDeepCompareMemo:** Implement useDeepCompareMemo ([#979](https://github.com/react-hookz/web/issues/979)) ([532cc41](https://github.com/react-hookz/web/commit/532cc41f3b2d55a7f6f297ea9a4b652072e0d311)), closes [#871](https://github.com/react-hookz/web/issues/871)

## [16.0.1](https://github.com/react-hookz/web/compare/v16.0.0...v16.0.1) (2022-10-22)


### Bug Fixes

* **useCustomCompareMemo:** Correctly infer the type of the value returned by the factory function ([#976](https://github.com/react-hookz/web/issues/976)) ([a625c55](https://github.com/react-hookz/web/commit/a625c55bc544dc1bc7544a5ff8811a0a78c568bd)), closes [#975](https://github.com/react-hookz/web/issues/975)

# [16.0.0](https://github.com/react-hookz/web/compare/v15.1.0...v16.0.0) (2022-10-09)


Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ import { useMountEffect } from '@react-hookz/web/esnext';

## Migrating from react-use

`@react-hookz/web` was built as a [spiritual successor](https://github.com/streamich/react-use/issues/1974) of `react-use` by one of its former maintainers.

Coming from `react-use`? Check out our
[migration guide](https://react-hookz.github.io/web/?path=/docs/migrating-from-react-use--page).

Expand Down Expand Up @@ -156,6 +158,9 @@ Coming from `react-use`? Check out our
— Like `useRef`, but it returns immutable ref that contains actual value.
- [**`useCustomCompareMemo`**](https://react-hookz.github.io/web/?path=/docs/miscellaneous-useCustomCompareMemo--example)
— Like useMemo but uses provided comparator function to validate dependency changes.
- [**`useDeepCompareMemo`**](https://react-hookz.github.io/web/?path=/docs/miscellaneous-useDeepCompareMemo--example)
— Like `useMemo` but uses `@react-hookz/deep-equal` comparator function to validate deep
dependency changes.
- [**`useHookableRef`**](https://react-hookz.github.io/web/?path=/docs/miscellaneous-usehookableref--example)
— Like `useRef` but it is possible to define get and set handlers.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@react-hookz/web",
"version": "16.0.0",
"version": "16.1.0",
"description": "React hooks done right, for browser and SSR.",
"keywords": [
"react",
Expand Down Expand Up @@ -107,7 +107,7 @@
"babel-loader": "^8.2.5",
"commitizen": "^4.2.5",
"commitlint": "^17.1.2",
"concurrently": "^7.4.0",
"concurrently": "^7.5.0",
"husky": "^8.0.1",
"jest": "^29.2.1",
"jest-environment-jsdom": "^29.2.1",
Expand Down
11 changes: 9 additions & 2 deletions src/__docs__/Introduction.story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Meta } from '@storybook/addon-docs';
[![Types](https://flat.badgen.net/npm/types/@react-hookz/web)](https://www.npmjs.com/package/@react-hookz/web)
[![Tree Shaking](https://flat.badgen.net/bundlephobia/tree-shaking/@react-hookz/web)](https://bundlephobia.com/result?p=@react-hookz/web)

× **[DOCS](https://react-hookz.github.io/web/)** × **[DISCORD](https://discord.gg/Fjwphtu65f)** ×
× **[GITHUB](https://github.com/react-hookz/web)** × **[DISCORD](https://discord.gg/Fjwphtu65f)** ×
**[CHANGELOG](https://github.com/react-hookz/web/blob/master/CHANGELOG.md)** ×

</div>
Expand All @@ -35,7 +35,7 @@ yarn add @react-hookz/web
```

As hooks was introduced to the world in React 16.8, `@react-hookz/web` requires - you guessed it -
`react` and `react-dom` 16.8+.
`react` and `react-dom` 16.8+.
Also, as React does not support IE, `@react-hookz/web` does not do so either. You'll have to
transpile your `node-modules` in order to run in IE.

Expand All @@ -58,3 +58,10 @@ import { useMountEffect } from '@react-hookz/web/esm';
// in case you want all the recent ES features
import { useMountEffect } from '@react-hookz/web/esnext';
```

## Migrating from react-use

`@react-hookz/web` was built as a [spiritual successor](https://github.com/streamich/react-use/issues/1974) of `react-use` by one of its former maintainers.

Coming from `react-use`? Check out our
[migration guide](https://react-hookz.github.io/web/?path=/docs/migrating-from-react-use--page).
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,5 @@ export { resolveHookState } from './util/resolveHookState';

// Types
export * from './types';

export { useDeepCompareMemo } from './useDeepCompareMemo/useDeepCompareMemo';
6 changes: 3 additions & 3 deletions src/useCustomCompareMemo/__docs__/story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export type DependenciesComparator<Deps extends DependencyList = DependencyList>
b: Deps
) => boolean;

function useCustomCompareMemo<Factory extends () => unknown, Deps extends DependencyList>(
factory: Factory,
function useCustomCompareMemo<T, Deps extends DependencyList>(
factory: () => T,
deps: Deps,
comparator: DependenciesComparator<Deps>
): ReturnType<Factory>;
): T
```

#### Importing
Expand Down
8 changes: 4 additions & 4 deletions src/useCustomCompareMemo/useCustomCompareMemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import type { DependenciesComparator } from '../types';
* @param comparator function to validate dependency changes
* @returns useMemo result
*/
export const useCustomCompareMemo = <Factory extends () => unknown, Deps extends DependencyList>(
factory: Factory,
export const useCustomCompareMemo = <T, Deps extends DependencyList>(
factory: () => T,
deps: Deps,
comparator: DependenciesComparator<Deps>
) => {
): T => {
const dependencies = useRef<Deps>();

if (dependencies.current === undefined || !comparator(dependencies.current, deps)) {
dependencies.current = deps;
}

// eslint-disable-next-line react-hooks/exhaustive-deps -- missing factory function
return useMemo(factory, dependencies.current);
return useMemo<T>(factory, dependencies.current);
};
1 change: 1 addition & 0 deletions src/useDeepCompareEffect/__docs__/story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ changes.

- SSR-friendly, meaning that comparator won't be called on the server.
- Ability to change underlying effect hook (default to `useEffect`).
- Uses yet fastest deep-comparator - [@react-hookz/deep-equal](https://github.com/react-hookz/deep-equal).

#### Example

Expand Down
27 changes: 27 additions & 0 deletions src/useDeepCompareMemo/__docs__/example.stories.tsx
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>
</>
);
};
42 changes: 42 additions & 0 deletions src/useDeepCompareMemo/__docs__/story.mdx
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.
31 changes: 31 additions & 0 deletions src/useDeepCompareMemo/__tests__/dom.ts
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);
});
});
13 changes: 13 additions & 0 deletions src/useDeepCompareMemo/__tests__/ssr.ts
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();
});
});
15 changes: 15 additions & 0 deletions src/useDeepCompareMemo/useDeepCompareMemo.ts
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);
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5732,10 +5732,10 @@ concat-stream@^1.5.0:
readable-stream "^2.2.2"
typedarray "^0.0.6"

concurrently@^7.4.0:
version "7.4.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.4.0.tgz#bb0e344964bc172673577c420db21e963f2f7368"
integrity sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA==
concurrently@^7.5.0:
version "7.5.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.5.0.tgz#4dd432d4634a8251f27ab000c4974e78e3906bd3"
integrity sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==
dependencies:
chalk "^4.1.0"
date-fns "^2.29.1"
Expand Down

0 comments on commit b5b776e

Please sign in to comment.