diff --git a/packages/rax-use-interval/README.md b/packages/rax-use-interval/README.md
new file mode 100644
index 0000000000..bc4b1842ee
--- /dev/null
+++ b/packages/rax-use-interval/README.md
@@ -0,0 +1,33 @@
+# 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}
;
+}
+```
+
+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/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..889f599c8a
--- /dev/null
+++ b/packages/rax-use-interval/src/index.js
@@ -0,0 +1,23 @@
+import { useEffect, useRef } from 'rax';
+
+function clearTimer(id) {
+ if (id != null) clearInterval(id);
+}
+
+export default function useInterval(fn, delay) {
+ const ref = useRef();
+
+ // Update to the latest function.
+ useEffect(() => {
+ ref.fn = fn;
+ }, [fn]);
+
+ useEffect(() => {
+ // 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
new file mode 100644
index 0000000000..3ba835f550
--- /dev/null
+++ b/packages/rax-use-timeout/README.md
@@ -0,0 +1,33 @@
+# 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}
;
+}
+```
+
+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/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..061d8cef06
--- /dev/null
+++ b/packages/rax-use-timeout/src/index.js
@@ -0,0 +1,23 @@
+import { useEffect, useRef } from 'rax';
+
+function clearTimer(id) {
+ if (id != null) clearTimeout(id);
+}
+
+export default function useTimeout(fn, delay) {
+ const ref = useRef();
+
+ // Update to the latest function.
+ useEffect(() => {
+ ref.fn = fn;
+ }, [fn]);
+
+ useEffect(() => {
+ // 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]);
+}