From c240758e08de6fda8599c4b1467c92ab951dfa36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=83=E5=BD=A6?= Date: Mon, 4 Nov 2019 19:16:10 +0800 Subject: [PATCH 1/3] feat: add useInterval and useTimeout --- packages/rax-use-interval/README.md | 17 +++++++++++++++++ packages/rax-use-interval/package.json | 21 +++++++++++++++++++++ packages/rax-use-interval/src/index.js | 22 ++++++++++++++++++++++ packages/rax-use-timeout/README.md | 17 +++++++++++++++++ packages/rax-use-timeout/package.json | 21 +++++++++++++++++++++ packages/rax-use-timeout/src/index.js | 23 +++++++++++++++++++++++ 6 files changed, 121 insertions(+) create mode 100644 packages/rax-use-interval/README.md create mode 100644 packages/rax-use-interval/package.json create mode 100644 packages/rax-use-interval/src/index.js create mode 100644 packages/rax-use-timeout/README.md create mode 100644 packages/rax-use-timeout/package.json create mode 100644 packages/rax-use-timeout/src/index.js diff --git a/packages/rax-use-interval/README.md b/packages/rax-use-interval/README.md new file mode 100644 index 0000000000..7faeb13463 --- /dev/null +++ b/packages/rax-use-interval/README.md @@ -0,0 +1,17 @@ +# rax-use-interval + +Why `useInterval`? `setInterval` will called even component is unmounted that make error happens, and `useInterval` will auto `clearInterval` before component will mount. + +```jsx +import { createElement } from 'rax'; +import useInterval from 'rax-use-interval'; + +function Example() { + const [count, setCount] = useState(0); + useInterval(() => { + setCount(count + 1); + }, 1000); + + return

{count}

; +} +``` \ No newline at end of file diff --git a/packages/rax-use-interval/package.json b/packages/rax-use-interval/package.json new file mode 100644 index 0000000000..1b19ef58e5 --- /dev/null +++ b/packages/rax-use-interval/package.json @@ -0,0 +1,21 @@ +{ + "name": "rax-use-interval", + "version": "1.0.0", + "description": "Rax useInterval hook", + "license": "BSD-3-Clause", + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/alibaba/rax.git" + }, + "bugs": { + "url": "https://github.com/alibaba/rax/issues" + }, + "homepage": "https://github.com/alibaba/rax#readme", + "engines": { + "npm": ">=3.0.0" + }, + "peerDependencies": { + "rax": "^1.0.0" + } +} diff --git a/packages/rax-use-interval/src/index.js b/packages/rax-use-interval/src/index.js new file mode 100644 index 0000000000..90d6a0b924 --- /dev/null +++ b/packages/rax-use-interval/src/index.js @@ -0,0 +1,22 @@ +import { useEffect, useRef } from 'rax'; + +function useInterval(fn, delay) { + const ref = useRef(); + + // Update to the latest function. + useEffect( + () => { + ref.fn = fn; + }, + [fn] + ); + + useEffect(() => { + if (delay !== null) { + let id = setInterval(ref.fn, delay); + return () => clearInterval(id); + } + }, [delay]); +} + +export default useInterval; \ No newline at end of file diff --git a/packages/rax-use-timeout/README.md b/packages/rax-use-timeout/README.md new file mode 100644 index 0000000000..b3015a5da3 --- /dev/null +++ b/packages/rax-use-timeout/README.md @@ -0,0 +1,17 @@ +# rax-use-timeout + +Why `useTimeout`? `setTimeout` will called even component is unmounted that make error happens, and `useTimeout` will auto `clearTimeout` before component will mount. + +```jsx +import { createElement } from 'rax'; +import useTimeout from 'rax-use-timeout'; + +function Example() { + const [count, setCount] = useState(0); + useTimeout(() => { + setCount(count + 1); + }, 1000); + + return

{count}

; +} +``` \ No newline at end of file diff --git a/packages/rax-use-timeout/package.json b/packages/rax-use-timeout/package.json new file mode 100644 index 0000000000..6ee9624316 --- /dev/null +++ b/packages/rax-use-timeout/package.json @@ -0,0 +1,21 @@ +{ + "name": "rax-use-timeout", + "version": "1.0.0", + "description": "Rax useTimeout hook", + "license": "BSD-3-Clause", + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/alibaba/rax.git" + }, + "bugs": { + "url": "https://github.com/alibaba/rax/issues" + }, + "homepage": "https://github.com/alibaba/rax#readme", + "engines": { + "npm": ">=3.0.0" + }, + "peerDependencies": { + "rax": "^1.0.0" + } +} diff --git a/packages/rax-use-timeout/src/index.js b/packages/rax-use-timeout/src/index.js new file mode 100644 index 0000000000..0b692ea58b --- /dev/null +++ b/packages/rax-use-timeout/src/index.js @@ -0,0 +1,23 @@ +import { useEffect, useRef } from 'rax'; + +function useTimeout(fn, delay) { + const ref = useRef(); + + // Update to the latest function. + useEffect( + () => { + ref.fn = fn; + }, + [fn] + ); + + useEffect( + () => { + const id = setTimeout(ref.fn, delay); + return () => clearTimeout(id); + }, + [delay] + ); +} + +export default useTimeout; \ No newline at end of file From ae9ddcfb052867425ec87380448dc5107676b29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=83=E5=BD=A6?= Date: Mon, 4 Nov 2019 19:28:20 +0800 Subject: [PATCH 2/3] style: format --- packages/rax-use-interval/src/index.js | 13 ++++--------- packages/rax-use-timeout/src/index.js | 26 +++++++++----------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/packages/rax-use-interval/src/index.js b/packages/rax-use-interval/src/index.js index 90d6a0b924..a33ad87018 100644 --- a/packages/rax-use-interval/src/index.js +++ b/packages/rax-use-interval/src/index.js @@ -1,15 +1,12 @@ import { useEffect, useRef } from 'rax'; -function useInterval(fn, delay) { +export default function useInterval(fn, delay) { const ref = useRef(); // Update to the latest function. - useEffect( - () => { - ref.fn = fn; - }, - [fn] - ); + useEffect(() => { + ref.fn = fn; + }, [fn]); useEffect(() => { if (delay !== null) { @@ -18,5 +15,3 @@ function useInterval(fn, delay) { } }, [delay]); } - -export default useInterval; \ No newline at end of file diff --git a/packages/rax-use-timeout/src/index.js b/packages/rax-use-timeout/src/index.js index 0b692ea58b..b8a705455f 100644 --- a/packages/rax-use-timeout/src/index.js +++ b/packages/rax-use-timeout/src/index.js @@ -1,23 +1,15 @@ import { useEffect, useRef } from 'rax'; -function useTimeout(fn, delay) { +export default function useTimeout(fn, delay) { const ref = useRef(); // Update to the latest function. - useEffect( - () => { - ref.fn = fn; - }, - [fn] - ); - - useEffect( - () => { - const id = setTimeout(ref.fn, delay); - return () => clearTimeout(id); - }, - [delay] - ); + useEffect(() => { + ref.fn = fn; + }, [fn]); + + useEffect(() => { + const id = setTimeout(ref.fn, delay); + return () => clearTimeout(id); + }, [delay]); } - -export default useTimeout; \ No newline at end of file From bc76f969ad3a73b7488872a7884cbd3962411ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=83=E5=BD=A6?= Date: Wed, 6 Nov 2019 22:58:19 +0800 Subject: [PATCH 3/3] feat: could stop and restart timer --- packages/rax-use-interval/README.md | 16 ++++++++++++++++ packages/rax-use-interval/src/index.js | 12 +++++++++--- packages/rax-use-timeout/README.md | 16 ++++++++++++++++ packages/rax-use-timeout/src/index.js | 12 ++++++++++-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/packages/rax-use-interval/README.md b/packages/rax-use-interval/README.md index 7faeb13463..bc4b1842ee 100644 --- a/packages/rax-use-interval/README.md +++ b/packages/rax-use-interval/README.md @@ -14,4 +14,20 @@ function Example() { return

{count}

; } +``` + +How to stop or restart timer? +```jsx +function Example() { + const [count, setCount] = useState(0); + const [delay, setDelay] = useState(1000); + useInterval(() => { + setCount(count + 1); + }, delay); + + const stopTimer = () => setDelay(null); // Stop + const restartTimer = () => setDelay(1000); // Restart + + return

{count}

; +} ``` \ No newline at end of file diff --git a/packages/rax-use-interval/src/index.js b/packages/rax-use-interval/src/index.js index a33ad87018..889f599c8a 100644 --- a/packages/rax-use-interval/src/index.js +++ b/packages/rax-use-interval/src/index.js @@ -1,5 +1,9 @@ import { useEffect, useRef } from 'rax'; +function clearTimer(id) { + if (id != null) clearInterval(id); +} + export default function useInterval(fn, delay) { const ref = useRef(); @@ -9,9 +13,11 @@ export default function useInterval(fn, delay) { }, [fn]); useEffect(() => { - if (delay !== null) { - let id = setInterval(ref.fn, delay); - return () => clearInterval(id); + // Clear before timer if delay time updated + clearTimer(ref.id); + if (typeof delay === 'number') { + ref.id = setInterval(() => ref.fn(), delay); + return () => clearTimer(ref.id); } }, [delay]); } diff --git a/packages/rax-use-timeout/README.md b/packages/rax-use-timeout/README.md index b3015a5da3..3ba835f550 100644 --- a/packages/rax-use-timeout/README.md +++ b/packages/rax-use-timeout/README.md @@ -14,4 +14,20 @@ function Example() { return

{count}

; } +``` + +How to stop or restart timer? +```jsx +function Example() { + const [count, setCount] = useState(0); + const [delay, setDelay] = useState(1000); + useTimeout(() => { + setCount(count + 1); + }, delay); + + const stopTimer = () => setDelay(null); // Stop + const restartTimer = () => setDelay(1000); // Restart + + return

{count}

; +} ``` \ No newline at end of file diff --git a/packages/rax-use-timeout/src/index.js b/packages/rax-use-timeout/src/index.js index b8a705455f..061d8cef06 100644 --- a/packages/rax-use-timeout/src/index.js +++ b/packages/rax-use-timeout/src/index.js @@ -1,5 +1,9 @@ import { useEffect, useRef } from 'rax'; +function clearTimer(id) { + if (id != null) clearTimeout(id); +} + export default function useTimeout(fn, delay) { const ref = useRef(); @@ -9,7 +13,11 @@ export default function useTimeout(fn, delay) { }, [fn]); useEffect(() => { - const id = setTimeout(ref.fn, delay); - return () => clearTimeout(id); + // Clear before timer if delay time updated + clearTimer(ref.id); + if (typeof delay === 'number') { + ref.id = setTimeout(() => ref.fn(), delay); + return () => clearTimer(ref.id); + } }, [delay]); }