mirror of
https://github.com/streamich/react-use.git
synced 2026-01-25 14:17:16 +00:00
commit
fb58e38642
@ -81,12 +81,10 @@
|
||||
<br/>
|
||||
- [**State**](./docs/State.md)
|
||||
- [`createMemo`](./docs/createMemo.md) — factory of memoized hooks.
|
||||
- [`useAdopt`](./docs/useAdopt.md) — extract value from multiple render-prop (or FaCC) components.
|
||||
- [`useCallbag`](./docs/useCallbag.md) — tracks latest value of a callbag.
|
||||
- [`useGetSet`](./docs/useGetSet.md) — returns state getter `get()` instead of raw state.
|
||||
- [`useGetSetState`](./docs/useGetSetState.md) — as if [`useGetSet`](./docs/useGetSet.md) and [`useSetState`](./docs/useSetState.md) had a baby.
|
||||
- [`useObservable`](./docs/useObservable.md) — tracks latest value of an `Observable`.
|
||||
- [`useRenderProp`](./docs/useRenderProp.md) — extracts value from a render-prop or a FaCC.
|
||||
- [`useSetState`](./docs/useSetState.md) — creates `setState` method which works like `this.setState`. [![][img-demo]](https://codesandbox.io/s/n75zqn1xp0)
|
||||
- [`useToggle` and `useBoolean`](./docs/useToggle.md) — tracks state of a boolean.
|
||||
- [`useCounter` and `useNumber`](./docs/useCounter.md) — tracks state of a number.
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
> __WARNING:__ Don't use this, works only for functional components.
|
||||
|
||||
# `useAdopt`
|
||||
|
||||
Extracts a values from multiple render-prop or FaCC components.
|
||||
This hook is similar to [`useRenderProp`](./useRenderProp.md), but
|
||||
it allows to specify a named map of multiple render-prop elements
|
||||
from which to extract values.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import {useAdopt} from 'react-use';
|
||||
|
||||
const FaCC = ({children}) => {
|
||||
return children('VALUE-FaCC');
|
||||
};
|
||||
const RenderProp = ({render}) => {
|
||||
return render('VALUE-RenderProp');
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [fragment, result] = useAdopt({
|
||||
facc: <FaCC/>,
|
||||
renderProp: <RenderProp/>,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{fragment}
|
||||
<div>FaCC: {result.facc[0]}</div>
|
||||
<div>Render prop: {result.renderProp[0]}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
@ -1,33 +0,0 @@
|
||||
> __WARNING:__ Don't use this, works only for functional components.
|
||||
|
||||
# `useRenderProp`
|
||||
|
||||
Extracts a value from render-prop or FaCC component.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import {useRenderProp} from 'react-use';
|
||||
|
||||
const FaCC = ({children}) => {
|
||||
return children('VALUE-FaCC');
|
||||
};
|
||||
const RenderProp = ({render}) => {
|
||||
return render('VALUE-RenderProp');
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [fragment1, [value1]] = useRenderProp(<FaCC />);
|
||||
const [fragment2, [value2]] = useRenderProp(<RenderProp />);
|
||||
|
||||
return (
|
||||
<>
|
||||
{fragment1}
|
||||
{fragment2}
|
||||
<div>FaCC: {value1}</div>
|
||||
<div>Render prop: {value2}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
@ -1,105 +0,0 @@
|
||||
import {storiesOf} from '@storybook/react';
|
||||
import * as React from 'react';
|
||||
import {useAdopt} from '..';
|
||||
import {useState} from 'react';
|
||||
import ShowDocs from '../util/ShowDocs';
|
||||
import {Spring} from 'react-spring';
|
||||
|
||||
const FaCC = ({children}) => {
|
||||
return children('VALUE-FaCC');
|
||||
};
|
||||
const RenderProp = ({render}) => {
|
||||
return render('VALUE-RenderProp');
|
||||
};
|
||||
|
||||
let values = [];
|
||||
let cnt = 0;
|
||||
const Spring2 = (props) => {
|
||||
if (cnt < 100) {
|
||||
props.children(...values);
|
||||
cnt++;
|
||||
}
|
||||
return <Spring {...props}>{(...res) => {
|
||||
values = res as any;
|
||||
return null;
|
||||
}}</Spring>
|
||||
};
|
||||
|
||||
let cnt2 = 0;
|
||||
|
||||
const Spring3 = (props) => {
|
||||
const [state, set] = useState<any[]>([]);
|
||||
|
||||
return (
|
||||
<Spring {...props}>{(...data) => {
|
||||
setTimeout(() => {
|
||||
set(data);
|
||||
props.children(...data);
|
||||
}, 1);
|
||||
return null;
|
||||
}}</Spring>
|
||||
);
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [fragment, result] = useAdopt({
|
||||
facc: <FaCC/>,
|
||||
renderProp: <RenderProp/>,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{fragment}
|
||||
<div>FaCC: {result.facc[0]}</div>
|
||||
<div>Render prop: {result.renderProp[0]}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AnimationSpring = () => {
|
||||
const style = {
|
||||
width: 200,
|
||||
height: 200,
|
||||
borderRadius: '100px',
|
||||
left: 50,
|
||||
position: 'fixed',
|
||||
background: 'red',
|
||||
};
|
||||
|
||||
return (
|
||||
<Spring3 from={{top: 0}} to={{top: 200}}>{(data) =>
|
||||
<div style={{...style, ...data} as any} />
|
||||
}</Spring3>
|
||||
);
|
||||
};
|
||||
|
||||
const Animation = () => {
|
||||
const [fragments, res] = useAdopt({animation: <Spring3 from={{top: 0}} to={{top: 200}}/>});
|
||||
const style = {
|
||||
width: 200,
|
||||
height: 200,
|
||||
borderRadius: '100px',
|
||||
left: 50,
|
||||
position: 'fixed',
|
||||
background: 'red',
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{fragments}
|
||||
<div style={{...style, ...res.animation[0]} as any} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf('State/useAdopt', module)
|
||||
.add('Docs', () => <ShowDocs md={require('../../docs/useAdopt.md')} />)
|
||||
.add('Demo', () =>
|
||||
<Demo/>
|
||||
)
|
||||
.add('AnimationSpring', () =>
|
||||
<AnimationSpring/>
|
||||
)
|
||||
.add('Animation', () =>
|
||||
<Animation/>
|
||||
)
|
||||
@ -3,14 +3,14 @@ import {storiesOf} from '@storybook/react';
|
||||
import {useAsync} from '..';
|
||||
import ShowDocs from '../util/ShowDocs';
|
||||
|
||||
const fn = () => new Promise((resolve) => {
|
||||
const fn = () => new Promise<string>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve('RESOLVED');
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
const Demo = () => {
|
||||
const {loading, value} = useAsync(fn);
|
||||
const {loading, value} = useAsync<string>(fn);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import {storiesOf} from '@storybook/react';
|
||||
import * as React from 'react';
|
||||
import {useRenderProp} from '..';
|
||||
import ShowDocs from '../util/ShowDocs';
|
||||
|
||||
const FaCC = ({children}) => {
|
||||
return children('VALUE-FaCC');
|
||||
};
|
||||
const RenderProp = ({render}) => {
|
||||
return render('VALUE-RenderProp');
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [fragment1, [value1]] = useRenderProp(<FaCC />);
|
||||
const [fragment2, [value2]] = useRenderProp(<RenderProp />);
|
||||
|
||||
return (
|
||||
<>
|
||||
{fragment1}
|
||||
{fragment2}
|
||||
<div>FaCC: {value1}</div>
|
||||
<div>Render prop: {value2}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf('State/useRenderProp', module)
|
||||
.add('Docs', () => <ShowDocs md={require('../../docs/useRenderProp.md')} />)
|
||||
.add('Demo', () =>
|
||||
<Demo/>
|
||||
)
|
||||
@ -1,5 +1,4 @@
|
||||
import createMemo from './createMemo';
|
||||
import useAdopt from './useAdopt';
|
||||
import useAsync from './useAsync';
|
||||
import useAudio from './useAudio';
|
||||
import useBattery from './useBattery';
|
||||
@ -31,7 +30,6 @@ import useOrientation from './useOrientation';
|
||||
import useOutsideClick from './useOutsideClick';
|
||||
import useRaf from './useRaf';
|
||||
import useRefMounted from './useRefMounted';
|
||||
import useRenderProp from './useRenderProp';
|
||||
import useSessionStorage from './useSessionStorage';
|
||||
import useSetState from './useSetState';
|
||||
import useSize from './useSize';
|
||||
@ -49,7 +47,6 @@ import useWait from './useWait';
|
||||
|
||||
export {
|
||||
createMemo,
|
||||
useAdopt,
|
||||
useAsync,
|
||||
useAudio,
|
||||
useBattery,
|
||||
@ -81,7 +78,6 @@ export {
|
||||
useOutsideClick,
|
||||
useRaf,
|
||||
useRefMounted,
|
||||
useRenderProp,
|
||||
useSessionStorage,
|
||||
useSetState,
|
||||
useSize,
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import useRenderProp from './useRenderProp';
|
||||
|
||||
const useAdopt = <T extends {[key: string]: any[]}>(map: {[key in keyof T]: React.ReactElement<any>}): [React.ReactElement<any>, T] => {
|
||||
const keys = Object.keys(map);
|
||||
const fragments: React.ReactElement<any>[] = [];
|
||||
const result: T = {} as T;
|
||||
|
||||
keys.sort();
|
||||
for (const key of keys) {
|
||||
const [fragment, value] = useRenderProp(map[key]);
|
||||
fragments.push(React.cloneElement(fragment, {key}));
|
||||
result[key] = value;
|
||||
}
|
||||
|
||||
return [React.createElement(React.Fragment, null, ...fragments), result];
|
||||
};
|
||||
|
||||
export default useAdopt;
|
||||
@ -3,10 +3,13 @@ import {useState, useEffect, useCallback} from 'react';
|
||||
export type AsyncState<T> =
|
||||
| {
|
||||
loading: true;
|
||||
error?: undefined;
|
||||
value?: undefined;
|
||||
}
|
||||
| {
|
||||
loading: false;
|
||||
error: Error;
|
||||
value?: undefined;
|
||||
}
|
||||
| {
|
||||
loading: false;
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import createMemo from './createMemo';
|
||||
|
||||
const {useState, useCallback} = React;
|
||||
|
||||
const useRenderProp = (element: React.ReactElement<any>): [React.ReactElement<any>, any[]] => {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!React.isValidElement(element)) {
|
||||
throw new TypeError(
|
||||
'useRenderProp element to be a valid React element ' +
|
||||
'such as <MyRenderProp />.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const [state, setState] = useState<any[]>([]);
|
||||
const useSetState = createMemo((...args) => setState(args));
|
||||
const render = useCallback((...args) => {
|
||||
useSetState(...args);
|
||||
return null;
|
||||
}, []);
|
||||
const cloned = React.cloneElement(element, {
|
||||
render,
|
||||
children: render,
|
||||
});
|
||||
|
||||
return [cloned, state];
|
||||
};
|
||||
|
||||
export default useRenderProp;
|
||||
@ -9556,10 +9556,10 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
|
||||
integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==
|
||||
typescript@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
|
||||
integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
|
||||
|
||||
ua-parser-js@^0.7.18:
|
||||
version "0.7.19"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user