- What Are Hooks? {#what-are-hooks}
- 什么是 Hooks?
- No Big Rewrites {#no-big-rewrites}
- 无重大重写
- Can I Use Hooks Today? {#can-i-use-hooks-today}
- 我现在可以用 Hooks 了吗?
- Tooling Support {#tooling-support}
- 工具支持
- What’s Next {#whats-next}
- 规划
- Testing Hooks {#testing-hooks}
- 测试 Hooks
- Thanks {#thanks}
- 致谢
- Installation {#installation}
- 安装
- Changelog {#changelog}
- 更新日志
- Hooks Changelog Since Alpha Versions {#hooks-changelog-since-alpha-versions}
- Hooks 自 Alpha 版本之后的更新日志 {#hooks-changelog-since-alpha-versions}
作者:Dan Abramov
With React 16.8, React Hooks are available in a stable release!
随着 React 发布 16.8 版本,React Hooks 也发布稳定版本啦!
What Are Hooks? {#what-are-hooks}
什么是 Hooks?
Hooks let you use state and other React features without writing a class. You can also build your own Hooks to share reusable stateful logic between components.
Hooks 允许你在不编写 class 的情况下使用状态(state)和其他 React 特性。 你还可以构建自己的 Hooks, 跨组件共享可重用的有状态逻辑。
If you’ve never heard of Hooks before, you might find these resources interesting:
如果你以前从未听说过 Hooks, 你可能会觉得这些资源很有趣:
- Introducing Hooks explains why we’re adding Hooks to React.
- Hooks at a Glance is a fast-paced overview of the built-in Hooks.
- Building Your Own Hooks demonstrates code reuse with custom Hooks.
- Making Sense of React Hooks explores the new possibilities unlocked by Hooks.
useHooks.com showcases community-maintained Hooks recipes and demos.
Hooks 介绍 解释了我们给 React 添加 Hooks 的原因。
- Hooks 概览 是对内置 Hooks 的快速概述。
- 构建自己的 Hooks 演示了如何使用自定义 Hooks 重用代码。
- 理解 React Hooks 探索了那些被 Hooks 解锁的新的可能。
- useHooks.com 展示了由社区维护的 Hooks 用法和 demos.
You don’t have to learn Hooks right now. Hooks have no breaking changes, and we have no plans to remove classes from React. The Hooks FAQ describes the gradual adoption strategy.
你不必现在就**学习 Hooks.** Hooks 没有重大变化,我们不计划从 React 中移除 class. Hooks FAQ 描述了我们逐步采纳的策略。
No Big Rewrites {#no-big-rewrites}
无重大重写
We don’t recommend rewriting your existing applications to use Hooks overnight. Instead, try using Hooks in some of the new components, and let us know what you think. Code using Hooks will work side by side with existing code using classes.
我们不建议你为了马上应用 Hooks 而重写现有应用。相反,我们建议你尝试在一些新的组件中使用 Hooks, 并且让我们了解你的想法。 使用 Hooks 的代码将与使用 class 的现有代码并行工作。
Can I Use Hooks Today? {#can-i-use-hooks-today}
我现在可以用 Hooks 了吗?
Yes! Starting with 16.8.0, React includes a stable implementation of React Hooks for:
可以的! 从 16.8.0 版本开始,React 包含一个稳定的 React Hooks 实现,可用于:
- React DOM
- React DOM 服务器(Server)
- React 测试渲染器(Test Renderer)
- React 浅层渲染器(Shallow Renderer)
Note that to enable Hooks, all React packages need to be 16.8.0 or higher. Hooks won’t work if you forget to update, for example, React DOM.
请注意,要启用 Hooks, 所有 React 包都必须升级到 16.8.0 或更高版本。 如果你忘记更新诸如 React DOM 之类的包,Hooks 将无法运行。
React Native will support Hooks in the 0.59 release.
React Native 将在 0.59 版本 支持 Hooks.
Tooling Support {#tooling-support}
工具支持
React Hooks are now supported by React DevTools. They are also supported in the latest Flow and TypeScript definitions for React. We strongly recommend enabling a new lint rule called eslint-plugin-react-hooks
to enforce best practices with Hooks. It will soon be included into Create React App by default.
React DevTools 现已支持 React Hooks, React 最新的 Flow 和 TypeScript 定义也支持它们。我们强烈建议你启用名为 eslint-plugin-react-hooks
的新 lint 规则来强制执行 Hooks 的最佳实践。Create React App 将很快包含它。
What’s Next {#whats-next}
规划
We described our plan for the next months in the recently published React Roadmap.
我们在最近发布的 React 路线图中描述了我们未来几个月的计划。
Note that React Hooks don’t cover all use cases for classes yet but they’re very close. Currently, only getSnapshotBeforeUpdate()
and componentDidCatch()
methods don’t have equivalent Hooks APIs, and these lifecycles are relatively uncommon. If you want, you should be able to use Hooks in most of the new code you’re writing.
请注意,React Hooks 尚未涵盖所有 class 的用例,但已经很接近了。 目前,只有 getSnapshotBeforeUpdate()
和 componentDidCatch()
方法没有等价的 Hooks API, 且这些生命周期相对不常见。 如果你想用 Hooks, 你可以在你正在写的大部分新代码中使用它。
Even while Hooks were in alpha, the React community created many interesting examples and recipes using Hooks for animations, forms, subscriptions, integrating with other libraries, and so on. We’re excited about Hooks because they make code reuse easier, helping you write your components in a simpler way and make great user experiences. We can’t wait to see what you’ll create next!
即使仍处于 alpha 状态,React 社区也使用 Hooks 为动画(animations),表单(forms),订阅(subscriptions),与其他库的集成(integrating)等创建了许多有趣的示例和用法。 我们为 Hooks 而雀跃 ,因为它们使代码更易重用,帮助你以更简单的方式编写组件,创建绝佳的用户体验。 我们迫不及待想知道你接下来会创造什么!
Testing Hooks {#testing-hooks}
测试 Hooks
We have added a new API called ReactTestUtils.act()
in this release. It ensures that the behavior in your tests matches what happens in the browser more closely. We recommend to wrap any code rendering and triggering updates to your components into act()
calls. Testing libraries can also wrap their APIs with it (for example, react-testing-library
‘s render
and fireEvent
utilities do this).
我们在这个版本中添加了一个名为 ReactTestUtils.act()
的新 API. 它可确保测试的行为与浏览器中的行为更加匹配。我们建议将所有代码渲染和组件更新触发封装到 act()
调用中。测试库也可以用它封装 API(举个例子,react-testing-library 的 render
和 fireEvent
工具就是这样做的)。
For example, the counter example from this page can be tested like this:
例如,此页面中的计数器示例可以这样进行测试:
import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import Counter from './Counter';
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null;
});
it('can render and update a counter', () => {
// Test first render and effect
// 测试首次渲染(render)及 effect
act(() => {
ReactDOM.render(<Counter />, container);
});
const button = container.querySelector('button');
const label = container.querySelector('p');
expect(label.textContent).toBe('You clicked 0 times');
expect(document.title).toBe('You clicked 0 times');
// Test second render and effect
// 测试二次渲染(render)及 effect
act(() => {
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
});
expect(label.textContent).toBe('You clicked 1 times');
expect(document.title).toBe('You clicked 1 times');
});
The calls to act()
will also flush the effects inside of them.
对 act()
的调用也会刷新它们内部的 effects.
If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote.
如果你需要测试自定义 Hook, 你可以在测试时创建组件,并使用它的 Hook. 然后就可以测试你写的组件了。
To reduce the boilerplate, we recommend using react-testing-library
which is designed to encourage writing tests that use your components as the end users do.
为了减少重复样板,我们建议使用 react-testing-library
, 它鼓励程序员编写模拟用户使用组件的行为的测试。
Thanks {#thanks}
致谢
We’d like to thank everybody who commented on the Hooks RFC for sharing their feedback. We’ve read all of your comments and made some adjustments to the final API based on them.
我们想向所有在 Hooks RFC 中分享反馈意见的人致谢。 我们已经阅读了你们的所有评论,并根据它们对最终 API 进行了一些调整。
Installation {#installation}
安装
React {#react}
React v16.8.0 is available on the npm registry.
React 16.8.0 版本已发布到 NPM 注册表。
To install React 16 with Yarn, run:
使用 Yarn 安装 React 16, 请运行:
yarn add react@^16.8.0 react-dom@^16.8.0
To install React 16 with npm, run:
使用 NPM 安装 React 16, 请运行:
npm install --save react@^16.8.0 react-dom@^16.8.0
We also provide UMD builds of React via a CDN:
我们还通过 CDN 提供 React 的 UMD 构建版本:
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
Refer to the documentation for detailed installation instructions.
详情请访问详细的安装。
ESLint Plugin for React Hooks {#eslint-plugin-for-react-hooks}
React Hooks 的 ESLint 插件
Note As mentioned above, we strongly recommend using the
eslint-plugin-react-hooks
lint rule. If you’re using Create React App, instead of manually configuring ESLint you can wait for the next version ofreact-scripts
which will come out shortly and will include this rule.注意 综上所述,我们强烈建议你使用 >
eslint-plugin-react-hooks
> lint 规则。 如果你正在使用 Create React App, 而不是手动配置 ESLint,你可以等待下一版本的 >react-scripts
> , 届时将包含此规则。
Assuming you already have ESLint installed, run:
假设你已经安装了 ESLint, 请运行:
# npm
npm install eslint-plugin-react-hooks@next --save-dev
# yarn
yarn add eslint-plugin-react-hooks@next --dev
Then add it to your ESLint configuration:
然后添加以下 ESLint 配置:
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error"
}
}
Changelog {#changelog}
更新日志
React {#react-1}
- Add Hooks — a way to use state and other React features without writing a class. (@acdlite et al. in #13968)
Improve the
useReducer
Hook lazy initialization API. (@acdlite in #14723)新增 Hooks —— 一种在不编写 class 的情况下使用状态(state)和其他 React 特性的方法。(@acdlite 等人提出于 #13968)
- 改进
useReducer
Hook 延迟初始化 API. (@acdlite 提出于 #14723)
React DOM {#react-dom}
- Bail out of rendering on identical values for
useState
anduseReducer
Hooks. (@acdlite in #14569) - Don’t compare the first argument passed to
useEffect
/useMemo
/useCallback
Hooks. (@acdlite in #14594) - Use
Object.is
algorithm for comparinguseState
anduseReducer
values. (@Jessidhia in #14752) - Support synchronous thenables passed to
React.lazy()
. (@gaearon in #14626) - Render components with Hooks twice in Strict Mode (DEV-only) to match class behavior. (@gaearon in #14654)
- Warn about mismatching Hook order in development. (@threepointone in #14585 and @acdlite in #14591)
Effect clean-up functions must return either
undefined
or a function. All other values, includingnull
, are not allowed. @acdlite in #14119避免为
useState
和useReducer
Hooks 传入相同值时进行的渲染。 (@acdlite 提出于 #14569)- 不比较传递给
useEffect
/useMemo
/useCallback
Hooks 的第一个参数。 (@gaearon 提出于 #14654) - 使用
Object.is
算法比较useState
和useReducer
的值。 (@Jessidhia 提出于 #14752) - 支持传递给
React.lazy()
的同步 thenable. (@gaearon 提出于 #14626) - 在严格模式(仅限 DEV)中使用 Hooks 两次渲染组件以匹配 class 行为。 (@gaearon 提出于 #14654)
- 在开发模式中 Hook 顺序不匹配时警告。 (@threepointone 提出于 #14585 及 @acdlite 提出于 #14591)
- Effect 清理功能必须返回
undefined
或函数。不允许包含null
在内的其他所有值。(@acdlite 提出于 #14119)
React Test Renderer {#react-test-renderer}
React 测试渲染器
- Support Hooks in the shallow renderer. (@trueadm in #14567)
- Fix wrong state in
shouldComponentUpdate
in the presence ofgetDerivedStateFromProps
for Shallow Renderer. (@chenesan in #14613) Add
ReactTestRenderer.act()
andReactTestUtils.act()
for batching updates so that tests more closely match real behavior. (@threepointone in #14744)- 在浅层渲染器中存在
getDerivedStateFromProps
的情况下,修复shouldComponentUpdate
中的错误状态。 (@chenesan 提出于 #14613) - 添加
ReactTestRenderer.act()
和ReactTestUtils.act()
以进行批处理更新,以便测试更接近真实行为。 (@threepointone 提出于 #14744)
ESLint Plugin: React Hooks {#eslint-plugin-react-hooks}
ESLint 插件: React Hooks {#eslint-plugin-react-hooks}
- Initial release. (@calebmer in #13968)
- Fix reporting after encountering a loop. (@calebmer and @Yurickh in #14661)
Don’t consider throwing to be a rule violation. (@sophiebits in #14040)
- 修复循环后的报告。 (@calebmer 及 @Yurickh 提出于 #14661)
- 不要把错误的抛出当作违反规则。 (@sophiebits 提出于 #14040)
Hooks Changelog Since Alpha Versions {#hooks-changelog-since-alpha-versions}
Hooks 自 Alpha 版本之后的更新日志 {#hooks-changelog-since-alpha-versions}
The above changelog contains all notable changes since our last stable release (16.7.0). As with all our minor releases, none of the changes break backwards compatibility.
上述更改日志包含自上次稳定版本(16.7.0)以来的所有重要更改。 与我们的所有 minor 版本一样,这些更改都不会破坏向后兼容性。
If you’re currently using Hooks from an alpha build of React, note that this release does contain some small breaking changes to Hooks. We don’t recommend depending on alphas in production code. We publish them so we can make changes in response to community feedback before the API is stable.
如果你正在使用来自 React alpha 版本的 Hooks, 请注意此版本确实包含对 Hooks 的一些小的重大更改。 我们不建议在生产代码中依赖 alpha. 我们发布它们是为了在 API 稳定之前根据的社区反馈进行更改。
Here are all breaking changes to Hooks that have been made since the first alpha release:
以下是自第一个 alpha 版本发布以来,我们对 Hooks 所做的所有重大更改:
- Remove
useMutationEffect
. (@sophiebits in #14336) - Rename
useImperativeMethods
touseImperativeHandle
. (@threepointone in #14565) - Bail out of rendering on identical values for
useState
anduseReducer
Hooks. (@acdlite in #14569) - Don’t compare the first argument passed to
useEffect
/useMemo
/useCallback
Hooks. (@acdlite in #14594) - Use
Object.is
algorithm for comparinguseState
anduseReducer
values. (@Jessidhia in #14752) - Render components with Hooks twice in Strict Mode (DEV-only). (@gaearon in #14654)
Improve the
useReducer
Hook lazy initialization API. (@acdlite in #14723)删除
useMutationEffect
. (@sophiebits 提出于 #14336)- 将
useImperativeMethods
重命名为useImperativeHandle
. (@threepointone 提出于 #14565) - 避免为
useState
和useReducer
Hooks 传入相同值时进行的渲染。 (@acdlite 提出于 #14569) - 不比较传递给
useEffect
/useMemo
/useCallback
Hooks 的第一个参数。 (@gaearon 提出于 #14654) - 使用
Object.is
算法比较useState
和useReducer
的值。 (@Jessidhia 提出于 #14752) - 在严格模式下仅使用 Hooks 两次渲染组件(仅限 DEV)。 (@gaearon 提出于 #14654)
- 改进
useReducer
Hook 延迟初始化 API. (@acdlite 提出于 #14723)