feat: add useUpdateEffect hook

This commit is contained in:
Va Da 2019-03-21 14:45:47 +01:00 committed by GitHub
commit c2afd23587
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 1 deletions

View File

@ -82,6 +82,7 @@
- [`useLogger`](./docs/useLogger.md) — logs in console as component goes through life-cycles.
- [`useMount`](./docs/useMount.md) — calls `mount` callbacks.
- [`useUnmount`](./docs/useUnmount.md) — calls `unmount` callbacks.
- [`useUpdateEffect`](./docs/useUpdateEffect.md) — run an `effect` only on updates.
<br/>
<br/>
- [**State**](./docs/State.md)

35
docs/useUpdateEffect.md Normal file
View File

@ -0,0 +1,35 @@
# `useUpdateEffect`
React effect hook that ignores the first invocation (e.g. on mount). The signature is exactly the same as the `useEffect` hook.
## Usage
```jsx
import React from 'react'
import {useUpdateEffect} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
const interval = setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => {
clearInterval(interval)
}
}, [])
useUpdateEffect(() => {
console.log('count', count) // will only show 1 and beyond
return () => { // *OPTIONAL*
// do something on unmount
}
}) // you can include deps array if necessary
return <div>Count: {count}</div>
};
```

View File

@ -0,0 +1,25 @@
import {storiesOf} from '@storybook/react';
import * as React from 'react';
import {useUpdateEffect} from '..';
const Demo = () => {
const [count, setCount] = React.useState(0)
const [didUpdate, setDidUpdate] = React.useState(false)
useUpdateEffect(() => {
setDidUpdate(true)
}, [count])
return (
<div>
<button onClick={() => setCount(count => count + 1)}>Count: {count}</button>
<p>Updated: {didUpdate}</p>
</div>
);
};
storiesOf('useUpdateEffect', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useUpdateEffect.md')} />)
.add('Demo', () =>
<Demo/>
)

View File

@ -49,6 +49,7 @@ import useUpdate from './useUpdate';
import useVideo from './useVideo';
import useWindowSize from './useWindowSize';
import useWait from './useWait';
import useUpdateEffect from './useUpdateEffect'
export {
createMemo,
@ -101,5 +102,6 @@ export {
useUpdate,
useVideo,
useWindowSize,
useWait
useWait,
useUpdateEffect
};

16
src/useUpdateEffect.ts Normal file
View File

@ -0,0 +1,16 @@
import { useRef, useEffect } from 'react'
const useUpdateEffect: typeof useEffect = (effect, deps) => {
const isInitialMount = useRef(true)
useEffect(
isInitialMount.current
? () => {
isInitialMount.current = false
}
: effect,
deps
)
}
export default useUpdateEffect