Skip to content

Commit

Permalink
feat: react 相关更新
Browse files Browse the repository at this point in the history
  • Loading branch information
minmaxw1024 committed Dec 16, 2024
1 parent 44e402e commit f81c7cd
Show file tree
Hide file tree
Showing 5 changed files with 788 additions and 0 deletions.
140 changes: 140 additions & 0 deletions posts/what_changes_in_react_v19_01_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
title: React 19 有哪些变化 - 1
published_at: 2024-12-09T15:00:00.000Z
snippet: React V19 change log 解读.
---

React 19 就这么突然的发布了, 其实在去年的 React 开发者大会上就有预告, 这个版本会带来一些重大的变化, 目前我们公司的技术栈已经从 Vue 迁移到了 React, 了解新的 React 变化对我来说还是挺重要的, 接下来几天我阅读 React 19 的官方博客, 把变化记录下来, 也方便大家了解.

## React 19 新特性总结

React 19 带来了很多新特性, 官方文档第一部分就是新特性的总结:

## 新功能:Actions

在 React 应用中,常见的需求是执行数据变更并更新状态,例如用户提交表单后修改名称。在 React 19 中,引入了 **Actions** 来自动管理这些操作,从而简化开发流程:

- **异步过渡**:支持使用 `useTransition` 自动管理 `isPending` 状态。
- **挂起状态**:Actions 提供了请求开始到结束的挂起状态。
- **乐观更新**:通过新钩子 `useOptimistic` 支持即时反馈。
- **错误处理**:Actions 提供内置的错误处理机制。
- **表单支持**:表单的 `action``formAction` 属性可以直接传递函数,自动提交并重置表单。

使用示例:

```javascript
function ChangeName({ name, setName }) {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get("name"));
if (error) return error;
redirect("/path");
return null;
},
null
);

return (
<form action={submitAction}>
<input name="name" defaultValue={name} />
<button disabled={isPending}>Update</button>
{error && <p>{error}</p>}
</form>
);
}
```

---

## 新钩子:`useActionState`

`useActionState` 用于简化 Actions 的常见用例:

- 接受一个异步函数并返回错误状态、提交函数和挂起状态。
- 适用于处理乐观更新和表单提交。

---

## 新钩子:`useOptimistic`

`useOptimistic` 支持在请求进行时显示乐观状态,操作完成后自动回退到真实状态。例如:

```javascript
function ChangeName({ currentName, onUpdateName }) {
const [optimisticName, setOptimisticName] = useOptimistic(currentName);

const submitAction = async (formData) => {
const newName = formData.get("name");
setOptimisticName(newName);
const updatedName = await updateName(newName);
onUpdateName(updatedName);
};

return (
<form action={submitAction}>
<input name="name" defaultValue={optimisticName} />
<button>Change Name</button>
</form>
);
}
```

---

## 新 API:`use`

React 19 提供了 `use` API,用于在渲染期间读取资源(例如 Promise 或 Context),支持挂起并自动切换状态:

```javascript
function Comments({ commentsPromise }) {
const comments = use(commentsPromise); // 自动挂起直到数据加载完成
return comments.map((comment) => <p>{comment}</p>);
}
```

注意事项:

- 不支持在渲染过程中创建的 Promise。
- 支持条件调用,未来可能扩展更多资源类型。

---

## React DOM 静态 API

新增两个静态站点生成 API:

- `prerender`
- `prerenderToNodeStream`

这些 API 支持等待数据加载并生成静态 HTML,适用于 Node.js 和 Web 流环境。

示例:

```javascript
import { prerender } from "react-dom/static";

async function handler(request) {
const { prelude } = await prerender(<App />, {
bootstrapScripts: ["/main.js"],
});
return new Response(prelude, { headers: { "content-type": "text/html" } });
}
```

---

## React Server Components

**服务器组件**允许在客户端应用或 SSR 服务器之外的环境中提前渲染组件:

- 稳定版本可用,但底层 API 尚未完全固定。
- 支持全栈 React 架构。

---

## Server Actions

**服务器操作**支持从客户端组件调用在服务器上执行的异步函数:

- 通过 `"use server"` 指令创建服务器操作。
- 服务器组件不需要特殊指令。
141 changes: 141 additions & 0 deletions posts/what_changes_in_react_v19_02_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
title: React 19 有哪些变化 - 2
published_at: 2024-12-10T15:00:00.000Z
snippet: React V19 change log 解读.
---

这篇文章在第二部分介绍了一些对之前特性的升级.

# React 19 新特性更新

## ref 作为 props 使用

在 React 19 中,函数组件可以直接将 `ref` 作为 `props` 访问,无需使用 `forwardRef`

```javascript
function MyInput({ placeholder, ref }) {
return <input placeholder={placeholder} ref={ref} />;
}

// 使用方式
<MyInput ref={ref} />;
```

### 改进点:

- 新的函数组件无需再使用 `forwardRef`
- React 将发布一个代码迁移工具(codemod)来自动更新现有代码。
- 在未来版本中,`forwardRef` 将会被废弃。

**注意**
传递给类组件的 `ref` 不会作为 `props` 传递,因为它们引用的是组件实例。

---

## 改进的 Hydration 错误报告

React 19 改进了在 `react-dom` 中的 hydration 错误报告。

### 旧错误日志:

在开发模式下,错误信息通常分散且缺乏具体上下文:

```console
Warning: Text content did not match. Server: “Server” Client: “Client”
...
```

### 新错误日志:

现在,React 会输出一条包含详细差异的错误信息:

```console
Uncaught Error: Hydration failed because the server rendered HTML didn’t match the client...
<App>
<span>
+ Client
- Server
```

### 可能的原因:

- 使用了客户端/服务器分支代码(如 `typeof window !== 'undefined'`)。
- 变量输入(如 `Date.now()``Math.random()`)。
- 本地化的日期格式化不一致。
- 没有同步 HTML 数据快照。
- 无效的 HTML 标签嵌套。
- 浏览器扩展导致的 HTML 修改。

更多信息请参阅 [hydration-mismatch 文档](https://react.dev/link/hydration-mismatch)

---

## <Context> 作为 Provider 使用

在 React 19 中,可以直接使用 `<Context>` 渲染 Context 提供者,而不再需要 `<Context.Provider>`

```javascript
const ThemeContext = createContext("");

function App({ children }) {
return <ThemeContext value="dark">{children}</ThemeContext>;
}
```

### 改进点:

- `<Context>` 可以直接作为提供者。
- 将发布迁移工具以转换现有 `<Context.Provider>` 实现。
- 在未来版本中,`<Context.Provider>` 将被废弃。

---

## refs 的清理函数

React 19 支持在 `ref` 回调中返回清理函数,用于在元素从 DOM 中移除时重置 `ref`

```javascript
<input
ref={(ref) => {
// 创建 ref
return () => {
// 清理 ref
};
}}
/>
```

### 改进点:

- 清理函数适用于 DOM refs、类组件 refs 以及 `useImperativeHandle`
- React 不再在卸载组件时调用带 `null` 的 ref 函数。

**注意**:由于清理函数的引入,TypeScript 现在会拒绝从 ref 回调中返回非清理函数的值。

修复示例:

```diff
- <div ref={(current) => (instance = current)} />
+ <div ref={(current) => { instance = current; }} />
```

可使用 `no-implicit-ref-callback-return` 的迁移工具修复该模式。

---

## `useDeferredValue` 初始值

React 19 为 `useDeferredValue` 添加了 `initialValue` 选项:

```javascript
function Search({ deferredValue }) {
const value = useDeferredValue(deferredValue, ""); // 初始值为 ''
return <Results query={value} />;
}
```

### 特性:

- 初次渲染时返回 `initialValue`,然后在后台重新渲染并使用 `deferredValue`

更多信息请参阅 [useDeferredValue 文档](https://react.dev/link/useDeferredValue)
Loading

0 comments on commit f81c7cd

Please sign in to comment.