From 84973de1a1fec41514b4becec6da0a3f3f241ee7 Mon Sep 17 00:00:00 2001 From: Ward Oosterlijnck Date: Sun, 31 Mar 2019 17:58:44 +1100 Subject: [PATCH 1/2] useEffectOnce --- README.md | 1 + docs/useEffectOnce.md | 27 +++++++++++++++++++++++++ src/__stories__/useEffectOnce.story.tsx | 21 +++++++++++++++++++ src/__stories__/util/ConsoleStory.tsx | 7 +++++++ src/index.ts | 2 ++ src/useEffectOnce.ts | 14 +++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 docs/useEffectOnce.md create mode 100644 src/__stories__/useEffectOnce.story.tsx create mode 100644 src/__stories__/util/ConsoleStory.tsx create mode 100644 src/useEffectOnce.ts diff --git a/README.md b/README.md index 4dad989901..74449a3cc6 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@

- [**Lifecycles**](./docs/Lifecycles.md) + - [`useEffectOnce`](./docs/useEffectOnce.md) — a modified [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) hook that only runs once. - [`useEvent`](./docs/useEvent.md) — subscribe to events. - [`useLifecycles`](./docs/useLifecycles.md) — calls `mount` and `unmount` callbacks. - [`useRefMounted`](./docs/useRefMounted.md) — tracks if component is mounted. diff --git a/docs/useEffectOnce.md b/docs/useEffectOnce.md new file mode 100644 index 0000000000..bb93bb6e89 --- /dev/null +++ b/docs/useEffectOnce.md @@ -0,0 +1,27 @@ +# `useEffectOnce` + +React lifecycle hook that runs an effect only once. + +## Usage + +```jsx +import {useEffectOnce} from 'react-use'; + +const Demo = () => { + useEffectOnce(() => { + console.log('Running effect once on mount') + + return () => { + console.log('Running clean-up of effect on unmount') + } + }); + + return null; +}; +``` + +## Reference + +```js +useEffectOnce(effect: EffectCallback); +``` diff --git a/src/__stories__/useEffectOnce.story.tsx b/src/__stories__/useEffectOnce.story.tsx new file mode 100644 index 0000000000..43bec8efc3 --- /dev/null +++ b/src/__stories__/useEffectOnce.story.tsx @@ -0,0 +1,21 @@ +import {storiesOf} from '@storybook/react'; +import * as React from 'react'; +import {useEffectOnce} from '..'; +import ConsoleStory from './util/ConsoleStory' +import ShowDocs from '../util/ShowDocs'; + +const Demo = () => { + useEffectOnce(() => { + console.log('Running effect once on mount') + + return () => { + console.log('Running clean-up of effect on unmount') + } + }); + + return ; +}; + +storiesOf('Lifecycles|useEffectOnce', module) + .add('Docs', () => ) + .add('Demo', () => ) diff --git a/src/__stories__/util/ConsoleStory.tsx b/src/__stories__/util/ConsoleStory.tsx new file mode 100644 index 0000000000..7109ce23ac --- /dev/null +++ b/src/__stories__/util/ConsoleStory.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const ConsoleStory = ({message = 'Open the developer console to see logs'}) => ( +

{message}

+); + +export default ConsoleStory diff --git a/src/index.ts b/src/index.ts index d8d15b398b..9b8f364024 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import useDropArea from './useDropArea'; import useCounter from './useCounter'; import useCss from './useCss'; import useDebounce from './useDebounce'; +import useEffectOnce from './useEffectOnce'; import useEvent from './useEvent'; import useFavicon from './useFavicon'; import useFullscreen from './useFullscreen'; @@ -77,6 +78,7 @@ export { useCounter, useCss, useDebounce, + useEffectOnce, useEvent, useFavicon, useFullscreen, diff --git a/src/useEffectOnce.ts b/src/useEffectOnce.ts new file mode 100644 index 0000000000..50badc6d83 --- /dev/null +++ b/src/useEffectOnce.ts @@ -0,0 +1,14 @@ +import {useRef, useEffect, EffectCallback} from 'react'; + +const useEffectOnce = (effect: EffectCallback) => { + const didRun = useRef(false); + + useEffect(() => { + if (!didRun.current) { + didRun.current = true; + return effect(); + } + }); +} + +export default useEffectOnce; From d2bb09dce82fe383cb755723d234255d410a417c Mon Sep 17 00:00:00 2001 From: Ward Oosterlijnck Date: Sun, 31 Mar 2019 19:30:22 +1100 Subject: [PATCH 2/2] Remove ref implementation useEffectOnce --- src/useEffectOnce.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/useEffectOnce.ts b/src/useEffectOnce.ts index 50badc6d83..65a411e6d7 100644 --- a/src/useEffectOnce.ts +++ b/src/useEffectOnce.ts @@ -1,14 +1,7 @@ -import {useRef, useEffect, EffectCallback} from 'react'; +import {useEffect, EffectCallback} from 'react'; const useEffectOnce = (effect: EffectCallback) => { - const didRun = useRef(false); - - useEffect(() => { - if (!didRun.current) { - didRun.current = true; - return effect(); - } - }); + useEffect(effect, []); } export default useEffectOnce;