diff --git a/snippets/useInterval.md b/snippets/useInterval.md index 478a8f7ed..ed91aaf47 100644 --- a/snippets/useInterval.md +++ b/snippets/useInterval.md @@ -8,7 +8,7 @@ A hook that implements `setInterval` in a declarative manner. - Create a custom hook that takes a `callback` and a `delay`. - Use the `React.useRef()` hook to create a `ref` for the callback function. - Use the `React.useEffect()` hook to remember the latest callback. -- Use the `Rect.useEffect()` hook to set up the interval. +- Use the `Rect.useEffect()` hook to set up the interval and clean up. ```jsx diff --git a/snippets/useTimeout.md b/snippets/useTimeout.md new file mode 100644 index 000000000..3b24f2a58 --- /dev/null +++ b/snippets/useTimeout.md @@ -0,0 +1,50 @@ +--- +title: useTimeout +tags: hooks,effect,intermediate +--- + +A hook that implements `setTimeout` in a declarative manner. + +- Create a custom hook that takes a `callback` and a `delay`. +- Use the `React.useRef()` hook to create a `ref` for the callback function. +- Use the `React.useEffect()` hook to remember the latest callback. +- Use the `Rect.useEffect()` hook to set up the timeout and clean up. + + +```jsx +const useTimeout = (callback, delay) => { + const savedCallback = React.useRef(); + + React.useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + React.useEffect(() => { + function tick () { + savedCallback.current(); + } + if (delay !== null) { + let id = setTimeout(tick, delay); + return () => clearTimeout(id); + } + }, [delay]); +}; +``` + +```jsx +const OneSecondTimer = (props) => { + const [seconds,setSeconds] = React.useState(0); + useTimeout(() => { + setSeconds(seconds + 1); + }, 1000); + + return ( +
{seconds}
+ ); +} + +ReactDOM.render( +