Skip to content

Commit 0d90f52

Browse files
committed
introducing a new hook useDeferredState
1 parent 7f8492f commit 0d90f52

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

text/0000-use-deferred-state.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
- Start Date: 2023-07-19
2+
- RFC PR: (leave this empty)
3+
- React Issue: (leave this empty)
4+
5+
# Summary
6+
7+
This proposal suggests simplifying the usage of `startTransition` in `React` by
8+
introducing a new hook.
9+
10+
# Basic example
11+
12+
Currently, in order to utilize `startTransition`, developers need to
13+
import `useTransition` and set it up as follows:
14+
15+
```js
16+
const [isPending, startTransition] = useTransition();
17+
```
18+
19+
However, in some cases, the `isPending` value is not used, but it still needs to be included because `startTransition` occupies the second index of the `useTransition` output. Additionally, `startTransition` often needs to work in conjunction with `useState`.
20+
21+
To address these complexities, I propose combining these hooks into a new one named `useDeferredState`
22+
23+
```js
24+
const [text, setText, isPending] = useDeferredState();
25+
```
26+
27+
Alternatively, we can achieve the same result using a HOF to wrap `useState`, like this:
28+
29+
```js
30+
const [text, setText, isPending] = deferred(useState());
31+
```
32+
33+
# Motivation
34+
The main motivation behind this proposal is to streamline the usage of `useTransition` and `startTransition` in `React`, making it more straightforward and intuitive for developers. By introducing a new hook or a HOF, we can enhance the developer experience and promote cleaner, more concise code when working with transitions in React.
35+
36+
# Detailed design
37+
`useDeferredState` and `deferred` are a combination of two main React hooks `useState` and `useTransition`.
38+
39+
By placing `isPending` as the third element in the output, it provides the flexibility to choose whether or not to utilize it in your code:
40+
```js
41+
// Use 'isPending' when needed:
42+
const [text, setText, isPending] = useDeferredState();
43+
44+
// Omit 'isPending' when not required:
45+
const [text, setText] = useDeferredState();
46+
```
47+
48+
# Drawbacks
49+
50+
- I think teaching `useTransition` is much harder than teaching `useDeferredState`
51+
- There is no breaking chaneg therefore there is no cost of migrating existing React applications.
52+
53+
# Alternatives
54+
55+
An alternative solution is having `useDeferredState` or `deferred` as
56+
a 3th-party package.
57+
58+
```js
59+
const useDeferredState = (initialValue) => {
60+
const [state, _setState] = useState(initialValue);
61+
const [isPenfing, startTransition] = useTransition();
62+
63+
const setState = useCallback((newValue) => {
64+
startTransition(() => {
65+
_setState(newValue);
66+
});
67+
}, []);
68+
69+
return [state, setState, isPenfing];
70+
}
71+
72+
// usage:
73+
const [text, setText, isPending] = useDeferredState();
74+
```
75+
76+
or
77+
78+
```js
79+
const deferred = ([state, _setState]) => {
80+
const [isPenfing, startTransition] = useTransition();
81+
82+
const setState = useCallback((newValue) => {
83+
startTransition(() => {
84+
_setState(newValue);
85+
});
86+
}, []);
87+
88+
return [state, setState, isPenfing];
89+
}
90+
91+
// usage:
92+
const [text, setText, isPending] = deferred(useState());
93+
```
94+
95+
# Adoption strategy
96+
97+
The proposed hook and Higher-Order Function are opt-in features, meaning that developers can
98+
choose whether or not to use them in their code. Existing React applications that don't require
99+
the new functionalities can continue using the traditional `useState` and `useTransition` approaches
100+
without any changes.
101+
102+
# How we teach this
103+
104+
`useDeferredState`:
105+
The proposed hook combines `useState` with a deferred state update mechanism to handle non-urgent updates. The term `deferred` accurately describes the behavior of the state update, as it delays execution until a later time (when React is less busy). This name aligns with React's existing hooks, such as `useEffect`, which also involve deferred operations.
106+
107+
`deferred`:
108+
When introducing the Higher-Order Function, it wraps useState to achieve similar functionality to the `useDeferredState` hook. The name `deferred` directly reflects the primary purpose of the function, emphasizing its role in handling state updates in a deferred manner.
109+
110+
# Unresolved questions
111+
Is there any downside if we use multiple `useTransition` in a component?

0 commit comments

Comments
 (0)