Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Yucohny authored Nov 13, 2023
2 parents c9a444d + a390fe5 commit ee79c35
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 83 deletions.
5 changes: 3 additions & 2 deletions src/components/Layout/Feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ const thumbsDownIcon = (
);

function sendGAEvent(isPositive: boolean) {
const category = isPositive ? 'like_button' : 'dislike_button';
const value = isPositive ? 1 : 0;
// Fragile. Don't change unless you've tested the network payload
// and verified that the right events actually show up in GA.
// @ts-ignore
gtag('event', 'feedback', {
event_category: 'button',
event_category: category,
event_label: window.location.pathname,
value,
event_value: value,
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout/Sidebar/SidebarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function SidebarLink({
{title}{' '}
{canary && (
<IconCanary
title="This feature is available in the latest Canary"
title=" - This feature is available in the latest Canary"
className="ms-2 text-gray-30 dark:text-gray-60 inline-block w-4 h-4 align-[-3px]"
/>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/PageHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function PageHeading({
{title}
{canary && (
<IconCanary
title="This feature is available in the latest Canary"
title=" - This feature is available in the latest Canary"
className="ms-4 mt-1 text-gray-50 dark:text-gray-40 inline-block w-6 h-6 align-[-1px]"
/>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/content/blog/2022/03/08/react-18-upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ function handleClick() {

在 React 18 工作组,我们和第三方库的维护者合作,创建需要支持 styles 和外部存储中的特定用例的并发渲染的新 API。为了支持 React 18,一些第三方库可能需要切换到下面的 API 之一:

* `useSyncExternalStore` 是一个新增 hook,它允许外部存储通过对 store 的强制更新保持同步从而支持并发读取。这个新 API 推荐用于任何和 React 的外部状态集成的库。了解更多信息请查看 [useSyncExternalStore 概览](https://github.com/reactwg/react-18/discussions/70)[useSyncExternalStore API 细节](https://github.com/reactwg/react-18/discussions/86)
* `useInsertionEffect` 是一个新增 hook,它可以让 CSS-in-JS 库解决渲染中注入样式的性能问题。我们希望只有在你已经构建了一个 CSS-in-JS 库的情况下才使用它。这个 hook 会在 DOM 变化之后, layout effect 读取新的布局之前运行。这解决了 React 17 及其以下就已经存在但是在 React 18 更重要的问题,因为在并发渲染期间 React 会阻止浏览器,给了它一个重新计算布局的机会。了解更多信息,查看 [`<style>` 库升级指南](https://github.com/reactwg/react-18/discussions/110)
* `useSyncExternalStore` 是一个新增 Hook,它允许外部存储通过对 store 的强制更新保持同步从而支持并发读取。这个新 API 推荐用于任何和 React 的外部状态集成的库。了解更多信息请查看 [useSyncExternalStore 概览](https://github.com/reactwg/react-18/discussions/70)[useSyncExternalStore API 细节](https://github.com/reactwg/react-18/discussions/86)
* `useInsertionEffect` 是一个新增 Hook,它可以让 CSS-in-JS 库解决渲染中注入样式的性能问题。我们希望只有在你已经构建了一个 CSS-in-JS 库的情况下才使用它。这个 Hook 会在 DOM 变化之后,layout effect 读取新的布局之前运行。这解决了 React 17 及其以下就已经存在但是在 React 18 更重要的问题,因为在并发渲染期间 React 会阻止浏览器,给了它一个重新计算布局的机会。了解更多信息,查看 [`<style>` 库升级指南](https://github.com/reactwg/react-18/discussions/110)

React 18 也引入了一些并发渲染的新 API,例如 `startTransition``useDeferredValue` 以及 `useId`,关于此更多信息我们在 [发布报告](/blog/2022/03/29/react-v18) 中有所分享。

Expand Down
11 changes: 5 additions & 6 deletions src/content/blog/2022/03/29/react-v18.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ startTransition(() => {
被包裹在 `startTransition` 中的更新会被处理为过渡更新,如果有紧急更新出现,比如点击或者按键,则会中断过渡更新。如果一个过渡更新被用户中断(比如,快速输入多个字符),React 将会抛弃未完成的渲染结果,然后仅渲染最新的内容。


* `useTransition`: 一个用于开启过渡更新的 hook,用于跟踪待定转场状态。
* `startTransition`: 当 hook 不能使用时,用于开启过渡的方法。
* `useTransition`: 一个用于开启过渡更新的 Hook,用于跟踪待定转场状态。
* `startTransition`: 当 Hook 不能使用时,用于开启过渡的方法。

并发渲染中将会加入过渡更新,允许更新被中断。如果更新内容被重新挂起,过渡机制也会告诉 React 在后台渲染过渡内容时继续展示当前内容(查看 [Suspense 意见征求](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md) 了解更多信息)。

Expand Down Expand Up @@ -229,8 +229,7 @@ React 18 中的 Suspense 在与 transition API 结合时效果最好。如果你

#### useId {/*useid*/}

`useId` 是一个新的 hook,用于生成在客户端和服务端两侧都独一无二的 id,避免 hydrate 后两侧内容不匹配。它主要用于需要唯一 id 的,具有集成 API 的组件库。这个更新不仅解决了一个在 React 17 及更低版本中的存在的问题,而且它会在 React 18 中发挥更重要的作用,因为新的流式服务端渲染响应 HTML 的方式将是无序的,需要独一无二的 id 作为索引。[参阅文档](/reference/react/useId)

`useId` 是一个新的Hook,用于生成在客户端和服务端两侧都独一无二的 id,避免 hydrate 后两侧内容不匹配。它主要用于需要唯一 id 的,具有集成 API 的组件库。这个更新不仅解决了一个在 React 17 及更低版本中的存在的问题,而且它会在 React 18 中发挥更重要的作用,因为新的流式服务端渲染响应 HTML 的方式将是无序的,需要独一无二的 id 作为索引。[参阅文档](/reference/react/useId)

> Note
>
Expand All @@ -246,15 +245,15 @@ React 18 中的 Suspense 在与 transition API 结合时效果最好。如果你

#### useSyncExternalStore {/*usesyncexternalstore*/}

`useSyncExternalStore` 是一个新的 hook,允许使用第三方状态管理来支持并发模式,并且能通过对 store 进行强制更新实现数据同步。对第三方数据源的订阅能力的实现上,消除了对 `useEffect` 的依赖,推荐任何 React 相关的第三方状态管理库使用这个新特性。[参阅文档](/reference/react/useSyncExternalStore)
`useSyncExternalStore` 是一个新的 Hook,允许使用第三方状态管理来支持并发模式,并且能通过对 store 进行强制更新实现数据同步。对第三方数据源的订阅能力的实现上,消除了对 `useEffect` 的依赖,推荐任何 React 相关的第三方状态管理库使用这个新特性。[参阅文档](/reference/react/useSyncExternalStore)

> Note
>
> `useSyncExternalStore` 旨在供库使用,而不是应用程序代码。
#### useInsertionEffect {/*useinsertioneffect*/}

`useInsertionEffect` 是一个新的 Hook ,允许 CSS-in-JS 库解决在渲染中注入样式的性能问题。除非你已经建立了一个 CSS-in-JS 库,否则我们不希望你使用它。这个 hook 将在 DOM 变更发生后,在 layout effect 获取新布局之前运行。这个功能不仅解决了一个在 React 17 及以下版本中已经存在的问题,而且在 React 18 中更加重要,因为 React 在并发渲染时会为浏览器让步,给它一个重新计算布局的机会。[参阅文档](/reference/react/useInsertionEffect)
`useInsertionEffect` 是一个新的 Hook ,允许 CSS-in-JS 库解决在渲染中注入样式的性能问题。除非你已经建立了一个 CSS-in-JS 库,否则我们不希望你使用它。这个 Hook 将在 DOM 变更发生后,在 layout effect 获取新布局之前运行。这个功能不仅解决了一个在 React 17 及以下版本中已经存在的问题,而且在 React 18 中更加重要,因为 React 在并发渲染时会为浏览器让步,给它一个重新计算布局的机会。[参阅文档](/reference/react/useInsertionEffect)

> Note
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ RSC 将面向服务器的多页面应用程序的简单“请求/响应”思维

自上次更新以来,我们已将 [RFC](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) 合并以批准提案。我们解决了 [React 服务器模块约定](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md) 提案中未解决的问题,并与我们的合作伙伴达成共识,采用 `use client` 协定。这些文件还作为符合 RSC 兼容实现应支持的规范。

最大的变化是我们引入了 [`async` / `await`](https://github.com/reactjs/rfcs/pull/229) 作为从服务器组件中进行数据提取的主要方式。我们还计划通过引入一个名为 `use` 的新钩子,从客户端支持数据加载,该钩子也将取消 Promises。虽然我们不能在仅限客户端的应用程序中的任意组件中支持 `async / await`,但我们计划在将客户端仅应用程序结构化类似于 RSC 应用程序的方式时添加支持。
最大的变化是我们引入了 [`async` / `await`](https://github.com/reactjs/rfcs/pull/229) 作为从服务器组件中进行数据提取的主要方式。我们还计划通过引入一个名为 `use` 的新 Hook,从客户端支持数据加载,该 Hook 也将取消 Promises。虽然我们不能在仅限客户端的应用程序中的任意组件中支持 `async / await`,但我们计划在将客户端仅应用程序结构化类似于 RSC 应用程序的方式时添加支持。

现在我们已经相当好地解决了数据提取的问题,我们正在探索另一个方向:从客户端向服务器发送数据,以便可以执行数据库变更和实现表单。我们通过在服务器/客户端边界传递 Server Action 函数来实现这一点。客户端可以调用该函数,提供无缝 RPC。而在 JavaScript 加载之前,Server Action 还可以提供逐步增强的表单。

Expand Down
20 changes: 10 additions & 10 deletions src/content/learn/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ TypeScript 是一种向 JavaScript 代码添加类型定义的常用方法。Typ
<YouWillLearn>

* [在 React 组件中使用 TypeScript](/learn/typescript#typescript-with-react-components)
* [带有 hooks 的类型示例](/learn/typescript#example-hooks)
* [带有 Hook 的类型示例](/learn/typescript#example-hooks)
* [来自 `@types/react` 的常见类型](/learn/typescript/#useful-types)
* [更多学习资源](/learn/typescript/#further-learning)

Expand Down Expand Up @@ -124,13 +124,13 @@ export default App = AppTSX;

## Hooks 示例 {/*example-hooks*/}

来自 `@types/react` 的类型定义包括内置的 hooks,因此你可以在组件中使用它们,无需任何额外设置。它们是根据你在组件中编写的代码构建的,所以你会得到很多 [类型推断](https://www.typescriptlang.org/docs/handbook/type-inference.html),并且理想情况下不需要处理提供类型的细节。
来自 `@types/react` 的类型定义包括内置的 Hook,因此你可以在组件中使用它们,无需任何额外设置。它们是根据你在组件中编写的代码构建的,所以你会得到很多 [类型推断](https://www.typescriptlang.org/docs/handbook/type-inference.html),并且理想情况下不需要处理提供类型的细节。

但是,我们可以看一下如何为 hooks 提供类型的几个示例。
但是,我们可以看一下如何为 Hook 提供类型的几个示例。

### `useState` {/*typing-usestate*/}

[`useState` hook](/reference/react/useState) 会重用作为初始 state 传入的值以确定值的类型。例如:
[`useState` Hook](/reference/react/useState) 会重用作为初始 state 传入的值以确定值的类型。例如:

```ts
// 推断类型为 "boolean"
Expand Down Expand Up @@ -166,7 +166,7 @@ const [requestState, setRequestState] = useState<RequestState>({ status: 'idle'

### `useReducer` {/*typing-usereducer*/}

[`useReducer`](/reference/react/useReducer) 是一个更复杂的 hook,它接受一个 reducer 函数和一个初始 state 作为参数,并将从初始 state 推断出 reducer 函数的类型。你可以选择性地为 `useReducer` 提供类型参数以为 state 提供类型。但是更高的做法仍然是在初始 state 上添加类型:
[`useReducer`](/reference/react/useReducer) 是一个更复杂的 Hook,它接受一个 reducer 函数和一个初始 state 作为参数,并将从初始 state 推断出 reducer 函数的类型。你可以选择性地为 `useReducer` 提供类型参数以为 state 提供类型。但是更高的做法仍然是在初始 state 上添加类型:

<Sandpack>

Expand Down Expand Up @@ -242,7 +242,7 @@ export default function App() {

### `useContext` {/*typing-usecontext*/}

[`useContext`](/reference/react/useContext) 是一种无需通过组件传递 props 而可以直接在组件树中传递数据的技术。它是通过创建 provider 组件使用,通常还会创建一个 hook 以在子组件中使用该值。
[`useContext`](/reference/react/useContext) 是一种无需通过组件传递 props 而可以直接在组件树中传递数据的技术。它是通过创建 provider 组件使用,通常还会创建一个 Hook 以在子组件中使用该值。

从传递给 `createContext` 调用的值推断 context 提供的值的类型:

Expand Down Expand Up @@ -286,7 +286,7 @@ export default App = AppTSX;

当你没有一个合理的默认值时,这种技术是有效的,而在这些情况下,`null` 作为默认值可能感觉是合理的。但是,为了让类型系统理解你的代码,你需要在 `createContext` 上显式设置 `ContextShape | null`

这会导致一个问题,你需要在 context consumer 中消除 `| null` 的类型。我们建议让 hook 在运行时检查它的存在,并在不存在时抛出一个错误:
这会导致一个问题,你需要在 context consumer 中消除 `| null` 的类型。我们建议让 Hook 在运行时检查它的存在,并在不存在时抛出一个错误:

```js {5, 16-20}
import { createContext, useContext, useState, useMemo } from 'react';
Expand All @@ -299,7 +299,7 @@ type ComplexObject = {
// 上下文在类型中创建为 `| null`,以准确反映默认值。
const Context = createContext<ComplexObject | null>(null);

// 这个 hook 会在运行时检查 context 是否存在,并在不存在时抛出一个错误。
// 这个 Hook 会在运行时检查 context 是否存在,并在不存在时抛出一个错误。
const useGetComplexObject = () => {
const object = useContext(Context);
if (!object) { throw new Error("useGetComplexObject must be used within a Provider") }
Expand Down Expand Up @@ -329,7 +329,7 @@ function MyComponent() {

### `useMemo` {/*typing-usememo*/}

[`useMemo`](/reference/react/useMemo) 会从函数调用中创建/重新访问记忆化值,只有在第二个参数中传入的依赖项发生变化时,才会重新运行该函数。函数的类型是根据第一个参数中函数的返回值进行推断的,如果希望明确指定,可以为这个钩子提供一个类型参数以指定函数类型
[`useMemo`](/reference/react/useMemo) 会从函数调用中创建/重新访问记忆化值,只有在第二个参数中传入的依赖项发生变化时,才会重新运行该函数。函数的类型是根据第一个参数中函数的返回值进行推断的,如果希望明确指定,可以为该 Hook 提供一个类型参数以指定函数类型

```ts
// 从 filterTodos 的返回值推断 visibleTodos 的类型
Expand All @@ -339,7 +339,7 @@ const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

### `useCallback` {/*typing-usecallback*/}

[`useCallback`](/reference/react/useCallback) 会在第二个参数中传入的依赖项保持不变的情况下,为函数提供相同的引用。与 `useMemo` 类似,函数的类型是根据第一个参数中函数的返回值进行推断的,如果希望明确指定,可以为这个钩子提供一个类型参数以指定函数类型
[`useCallback`](/reference/react/useCallback) 会在第二个参数中传入的依赖项保持不变的情况下,为函数提供相同的引用。与 `useMemo` 类似,函数的类型是根据第一个参数中函数的返回值进行推断的,如果希望明确指定,可以为这个 Hook 提供一个类型参数以指定函数类型


```ts
Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/use-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ export default function Counter({initialValue = 0}) {

</Sandpack>

As `Counter` requires both the `useState` hook and event handlers to increment or decrement the value, this component must be a Client Component and will require a `'use client'` directive at the top.
As `Counter` requires both the `useState` Hook and event handlers to increment or decrement the value, this component must be a Client Component and will require a `'use client'` directive at the top.

In contrast, a component that renders UI without interaction will not need to be a Client Component.

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/useOptimistic.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default function App() {
]);
async function sendMessage(formData) {
const sentMessage = await deliverMessage(formData.get("message"));
setMessages([...messages, { text: sentMessage }]);
setMessages((messages) => [...messages, { text: sentMessage }]);
}
return <Thread messages={messages} sendMessage={sendMessage} />;
}
Expand Down
Loading

0 comments on commit ee79c35

Please sign in to comment.