From 3b6d37e1ef4dc40a92411ed2ca43a824984da00d Mon Sep 17 00:00:00 2001 From: Behnam Mohammadi Date: Wed, 25 Aug 2021 11:35:22 +0430 Subject: [PATCH 1/4] introduce a new hook that called useStateRef --- text/0000-use-state-ref.md | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 text/0000-use-state-ref.md diff --git a/text/0000-use-state-ref.md b/text/0000-use-state-ref.md new file mode 100644 index 00000000..7d1ed894 --- /dev/null +++ b/text/0000-use-state-ref.md @@ -0,0 +1,84 @@ +- Start Date: 2021-08-24 +- RFC PR: (leave this empty) +- React Issue: (leave this empty) + +# Summary + +Introduce a new hook to reduce/improve some process. + +# Basic example + +In this example `useEffect` doesn't need a dependency for read updated `count`'s value, so +that's mean whenever `count` changes we don't need to perform `useEffect` effect function. +`useStateRef` just is a name, so might we need to change to better name. + +```js +const [count, setCount, getCount] = useStateRef(); + +useEffect(() => { + const handleVisibiltuy = () => { + console.log(getCount()); + }; + + document.addEventListener('visibilitychange', handleVisibiltuy); + + return () => document.removeEventListener('visibilitychange', handleVisibiltuy); +}, []); +``` + +Also, in this example `useCallback` doesn't need a dependency to know `count`'s value, so +`useCallback` inside function just perform once. + +```js +const [count, setCount, getCount] = useStateRef(); + +const handleClick = useCallback(() => { + console.log(getCount()); +}, []); +``` + +# Motivation + +`useEffect` and `useCallback` needs to know dependencies to redefine `function` depended +on new values of dependencies. but these are redundant process for `React` because we don't +know what time we need it exactly ex: `handleClick` depend on user behavior so we just need +`count`'s value when user need it. + +# Detailed design + +A basic of implementation for `useStateRef` that we can use in project is: +```js +function useStateRef(initialValue: T): [T, (nextState: T) => void, () => T] { + const [state, setState] = useState(initialValue); + const stateRef = useRef(state); + stateRef.current = state; + const getState = useCallback(() => stateRef.current, []); + return [state, setState, getState]; +} +``` + +# Drawbacks + +This is a new hook, so we don't have any breaking change, also we can implement that by +internal hook. + +# Alternatives + +Alternative can be a package, maybe + +# Adoption strategy + +Fortunately we don't have any breaking change, also we can embed this hook to `useState` without +breaking change + +```js +const [count, setCount, getCount] = useState(); +``` + +# How we teach this + +This RFC introduce a new hook, so we have to add some section to React documentation + +# Unresolved questions + +- do we need to implement a new hook or embed it to `useState`? \ No newline at end of file From e81cdf70afe59abc49421f385a030bdbe8a45adb Mon Sep 17 00:00:00 2001 From: Behnam Mohammadi Date: Wed, 25 Aug 2021 12:59:51 +0430 Subject: [PATCH 2/4] fix typo --- text/0000-use-state-ref.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/text/0000-use-state-ref.md b/text/0000-use-state-ref.md index 7d1ed894..8fe01396 100644 --- a/text/0000-use-state-ref.md +++ b/text/0000-use-state-ref.md @@ -8,26 +8,26 @@ Introduce a new hook to reduce/improve some process. # Basic example -In this example `useEffect` doesn't need a dependency for read updated `count`'s value, so -that's mean whenever `count` changes we don't need to perform `useEffect` effect function. -`useStateRef` just is a name, so might we need to change to better name. +In this example we see `useEffect` that doesn't need a dependency to read updated `count`'s +value, so that's mean we don't need to perform `useEffect` effect function event `count` will +change. `useStateRef` just is a name, so might we need to change to better name. ```js const [count, setCount, getCount] = useStateRef(); useEffect(() => { - const handleVisibiltuy = () => { + const handleVisibility = () => { console.log(getCount()); }; - document.addEventListener('visibilitychange', handleVisibiltuy); + document.addEventListener('visibilitychange', handleVisibility); - return () => document.removeEventListener('visibilitychange', handleVisibiltuy); + return () => document.removeEventListener('visibilitychange', handleVisibility); }, []); ``` Also, in this example `useCallback` doesn't need a dependency to know `count`'s value, so -`useCallback` inside function just perform once. +`useCallback` inside function just perform once. that's awesome ```js const [count, setCount, getCount] = useStateRef(); @@ -60,7 +60,7 @@ function useStateRef(initialValue: T): [T, (nextState: T) => void, () => T] { # Drawbacks This is a new hook, so we don't have any breaking change, also we can implement that by -internal hook. +internal React hooks. # Alternatives From e1c0887a23eb31e7c8ca19510abb73d934e0118b Mon Sep 17 00:00:00 2001 From: Behnam Mohammadi Date: Thu, 28 Oct 2021 22:01:09 +0330 Subject: [PATCH 3/4] fix typo --- text/0000-use-state-ref.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/text/0000-use-state-ref.md b/text/0000-use-state-ref.md index 8fe01396..c55c67d4 100644 --- a/text/0000-use-state-ref.md +++ b/text/0000-use-state-ref.md @@ -4,13 +4,11 @@ # Summary -Introduce a new hook to reduce/improve some process. +Introduce a new hook to reduce/improve some processes. # Basic example -In this example we see `useEffect` that doesn't need a dependency to read updated `count`'s -value, so that's mean we don't need to perform `useEffect` effect function event `count` will -change. `useStateRef` just is a name, so might we need to change to better name. +In this example we see `useEffect` that doesn't need a dependency to read updated `count`'s value, so that's mean we don't need to perform `useEffect` effect function event `count` will change. `useStateRef` just is a name, so might we need to change to a better name. ```js const [count, setCount, getCount] = useStateRef(); @@ -26,8 +24,7 @@ useEffect(() => { }, []); ``` -Also, in this example `useCallback` doesn't need a dependency to know `count`'s value, so -`useCallback` inside function just perform once. that's awesome +Also, in this example `useCallback` doesn't need a dependency to know `count`'s value, so `useCallback` inside function just performs once. that's awesome ```js const [count, setCount, getCount] = useStateRef(); @@ -39,10 +36,7 @@ const handleClick = useCallback(() => { # Motivation -`useEffect` and `useCallback` needs to know dependencies to redefine `function` depended -on new values of dependencies. but these are redundant process for `React` because we don't -know what time we need it exactly ex: `handleClick` depend on user behavior so we just need -`count`'s value when user need it. +`useEffect` and `useCallback` need to know dependencies to redefine `function` depended on new values of dependencies. but these are redundant process for `React` because we don't know what time we need it exactly ex: `handleClick` depend on user behavior so we just need `count`'s value when the user needs it. # Detailed design @@ -59,8 +53,7 @@ function useStateRef(initialValue: T): [T, (nextState: T) => void, () => T] { # Drawbacks -This is a new hook, so we don't have any breaking change, also we can implement that by -internal React hooks. +This is a new hook, so we don't have any breaking change, also we can implement that by internal React hooks. # Alternatives @@ -68,8 +61,7 @@ Alternative can be a package, maybe # Adoption strategy -Fortunately we don't have any breaking change, also we can embed this hook to `useState` without -breaking change +Fortunately, we don't have any breaking change, also we can embed this hook to `useState` without breaking change ```js const [count, setCount, getCount] = useState(); From 0dfb3fe9b283024460f144efddca93081d41d228 Mon Sep 17 00:00:00 2001 From: Behnam Mohammadi Date: Sun, 23 Jan 2022 10:13:30 +0330 Subject: [PATCH 4/4] add js version --- text/0000-use-state-ref.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/text/0000-use-state-ref.md b/text/0000-use-state-ref.md index c55c67d4..bf639d0f 100644 --- a/text/0000-use-state-ref.md +++ b/text/0000-use-state-ref.md @@ -24,7 +24,7 @@ useEffect(() => { }, []); ``` -Also, in this example `useCallback` doesn't need a dependency to know `count`'s value, so `useCallback` inside function just performs once. that's awesome +Also, in this example, `useCallback` doesn't need a dependency to know `count`'s value, so `useCallback` inside function just performs once. that's awesome ```js const [count, setCount, getCount] = useStateRef(); @@ -41,6 +41,9 @@ const handleClick = useCallback(() => { # Detailed design A basic of implementation for `useStateRef` that we can use in project is: + +TS version: + ```js function useStateRef(initialValue: T): [T, (nextState: T) => void, () => T] { const [state, setState] = useState(initialValue); @@ -51,6 +54,18 @@ function useStateRef(initialValue: T): [T, (nextState: T) => void, () => T] { } ``` +JS version: + +```js +function useStateRef(initialValue) { + const [state, setState] = useState(initialValue); + const stateRef = useRef(state); + stateRef.current = state; + const getState = useCallback(() => stateRef.current, []); + return [state, setState, getState]; +} +``` + # Drawbacks This is a new hook, so we don't have any breaking change, also we can implement that by internal React hooks. @@ -73,4 +88,4 @@ This RFC introduce a new hook, so we have to add some section to React documenta # Unresolved questions -- do we need to implement a new hook or embed it to `useState`? \ No newline at end of file +- do we need to implement a new hook or embed it to `useState`?