Skip to content

Commit 05cb907

Browse files
authored
feat: react 19 (#149)
* chore: React 19 * feat: 补充 useOptimistic 作为草稿 * rf: 调整日志
1 parent 11b70aa commit 05cb907

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

_posts/2024/2024-12-06-react-19.md

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
title: React 19
3+
categories: [react]
4+
author: iugo
5+
---
6+
7+
React 19 终于正式发布了: <https://react.dev/blog/2024/12/05/react-19>
8+
9+
新版本中新增了许多功能, 其中, 一些功能是我们重点关注的:
10+
11+
1. `useActionState`
12+
2. `use`
13+
3. `useOptimistic`
14+
4. `ref` 作为 props 传递
15+
16+
## useActionState
17+
18+
在使用 useActionState 的时候, 我们需要注意的是, 在函数内部能否调用 setState
19+
函数对数据进行部分修改.
20+
21+
官方演示非常清晰, 这里稍作修改:
22+
23+
```tsx
24+
function DataTable({ name }) {
25+
const [result, updateData, isPending] = useActionState(
26+
async (previousState, name) => {
27+
const result = await getDataPromise(name);
28+
return result;
29+
},
30+
new Result(),
31+
);
32+
33+
return (
34+
<>
35+
<Table data={result} isPending={isPending} />
36+
<button
37+
type="submit"
38+
disabled={isPending}
39+
onClick={() => {
40+
updateData(name);
41+
}}
42+
>
43+
Update
44+
</button>
45+
</>
46+
);
47+
}
48+
```
49+
50+
## use
51+
52+
use 仍然不是一定足够可靠的功能. 之前 React 团队就说了 use 的局限性, 现在
53+
React 19 仍然没有解决这个问题.
54+
55+
我们预期仅在初始化数据的时候使用 use, 在更新数据的时候仍使用 useState.
56+
在组件中, 同时保有这两种状态管理的方式, 比如:
57+
58+
```tsx
59+
function MyComponent() {
60+
const initData = use(getDataPromise());
61+
// 👆 因为现在不能在渲染组件中创建 Promise, 所以现在会报错
62+
const [data, setData] = useState<Data | null>(null);
63+
const currentData = useMemo(() => data ?? initData, [data, initData]);
64+
65+
return (
66+
<>
67+
{currentData}
68+
<button
69+
onClick={async () => {
70+
const data = await getDataPromise();
71+
setData(data);
72+
}}
73+
>
74+
Set Data
75+
</button>
76+
</>
77+
);
78+
}
79+
```
80+
81+
不过, 如何我们区分初始化数据和更新数据, 仅在系统初始化数据的时候使用 use,
82+
那么 use 仍然是一个非常有用的功能. 比如:
83+
84+
```tsx
85+
const configPromise = getConfigPromise();
86+
87+
function MyComponent() {
88+
const config = use(configPromise);
89+
const [data, setData] = useState<Data | null>(null);
90+
91+
return (
92+
<>
93+
{data}
94+
<button
95+
onClick={async () => {
96+
const data = await getDataPromise(config);
97+
setData(data);
98+
}}
99+
>
100+
Set Data
101+
</button>
102+
</>
103+
);
104+
}
105+
```
106+
107+
## useOptimistic
108+
109+
在上面的例子中, 我们区分了 initData, data 和 currentData. 在 React 19 中,
110+
我们使用 useOptimistic 可以对前端预计修改成功的数据进行优化. 比如:
111+
112+
```tsx
113+
function MyComponent() {
114+
const [data, setData] = useState<Data | null>(null);
115+
const [currentData, setOptimisticData] = useOptimistic(data);
116+
117+
return (
118+
<>
119+
{currentData}
120+
<button
121+
onClick={async () => {
122+
setOptimisticData(tempData);
123+
const data = await getDataPromise(tempData);
124+
setData(data);
125+
}}
126+
>
127+
Set Data
128+
</button>
129+
</>
130+
);
131+
}
132+
```
133+
134+
在大多数情况下, 这是一个纯优化, 并不会功能有影响.
135+
136+
这种优化甚至还有负面效果, 比如:
137+
138+
1. 如果用户在点击按钮之后, 已经渲染了新的数据, 这时用户认为已经完成.
139+
2. 然后, 如果后端数据更新失败, 那么数据会重置回错误之前的数据, 但用户不一定会注意到.
140+
141+
## ref 作为 props 传递
142+
143+
之前, ref 作为 props 传递的时候时会报错. 需要使用 forwardRef 来传递.
144+
但是, 现在 React 19 中, 不再需要使用 forwardRef 来传递, 可以直接传递 ref.
145+
146+
官方演示为:
147+
148+
```tsx
149+
function MyInput({placeholder, ref}) {
150+
return <input placeholder={placeholder} ref={ref} />
151+
}
152+
153+
//...
154+
<MyInput ref={ref} />
155+
```

0 commit comments

Comments
 (0)