Skip to content

Commit b6a753b

Browse files
add update everything
2 parents 5e4aa68 + 98c1d22 commit b6a753b

22 files changed

+791
-62
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
---
2+
title: "React v16.8: The One With Hooks"
3+
author: [gaearon]
4+
---
5+
6+
With React 16.8, [React Hooks](/docs/hooks-intro.html) are available in a stable release!
7+
8+
## What Are Hooks?
9+
10+
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.
11+
12+
If you've never heard of Hooks before, you might find these resources interesting:
13+
14+
* [Introducing Hooks](/docs/hooks-intro.html) explains why we're adding Hooks to React.
15+
* [Hooks at a Glance](/docs/hooks-overview.html) is a fast-paced overview of the built-in Hooks.
16+
* [Building Your Own Hooks](/docs/hooks-custom.html) demonstrates code reuse with custom Hooks.
17+
* [Making Sense of React Hooks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) explores the new possibilities unlocked by Hooks.
18+
* [useHooks.com](https://usehooks.com/) showcases community-maintained Hooks recipes and demos.
19+
20+
**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](/docs/hooks-faq.html) describes the gradual adoption strategy.
21+
22+
## No Big Rewrites
23+
24+
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](/docs/hooks-intro.html#gradual-adoption-strategy) with existing code using classes.
25+
26+
## Can I Use Hooks Today?
27+
28+
Yes! Starting with 16.8.0, React includes a stable implementation of React Hooks for:
29+
30+
* React DOM
31+
* React DOM Server
32+
* React Test Renderer
33+
* React Shallow Renderer
34+
35+
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.
36+
37+
**React Native will support Hooks in the [0.59 release](https://github.com/react-native-community/react-native-releases/issues/79#issuecomment-457735214).**
38+
39+
## Tooling Support
40+
41+
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`](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce best practices with Hooks. It will soon be included into Create React App by default.
42+
43+
## What's Next
44+
45+
We described our plan for the next months in the recently published [React Roadmap](/blog/2018/11/27/react-16-roadmap.html).
46+
47+
Note that React Hooks don't cover *all* use cases for classes yet but they're [very close](/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes). 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.
48+
49+
Even while Hooks were in alpha, the React community created many interesting [examples](https://codesandbox.io/react-hooks) and [recipes](https://usehooks.com) 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!
50+
51+
## Testing Hooks
52+
53+
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`](https://github.com/kentcdodds/react-testing-library)'s `render` and `fireEvent` utilities do this).
54+
55+
For example, the counter example from [this page](/docs/hooks-effect.html) can be tested like this:
56+
57+
```js{3,20-22,29-31}
58+
import React from 'react';
59+
import ReactDOM from 'react-dom';
60+
import { act } from 'react-dom/test-utils';
61+
import Counter from './Counter';
62+
63+
let container;
64+
65+
beforeEach(() => {
66+
container = document.createElement('div');
67+
document.body.appendChild(container);
68+
});
69+
70+
afterEach(() => {
71+
document.body.removeChild(container);
72+
container = null;
73+
});
74+
75+
it('can render and update a counter', () => {
76+
// Test first render and effect
77+
act(() => {
78+
ReactDOM.render(<Counter />, container);
79+
});
80+
const button = container.querySelector('button');
81+
const label = container.querySelector('p');
82+
expect(label.textContent).toBe('You clicked 0 times');
83+
expect(document.title).toBe('You clicked 0 times');
84+
85+
// Test second render and effect
86+
act(() => {
87+
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
88+
});
89+
expect(label.textContent).toBe('You clicked 1 times');
90+
expect(document.title).toBe('You clicked 1 times');
91+
});
92+
```
93+
94+
The calls to `act()` will also flush the effects inside of them.
95+
96+
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.
97+
98+
To reduce the boilerplate, we recommend using [`react-testing-library`](https://git.io/react-testing-library) which is designed to encourage writing tests that use your components as the end users do.
99+
100+
## Thanks
101+
102+
We'd like to thank everybody who commented on the [Hooks RFC](https://github.com/reactjs/rfcs/pull/68) for sharing their feedback. We've read all of your comments and made some adjustments to the final API based on them.
103+
104+
## Installation
105+
106+
### React
107+
108+
React v16.8.0 is available on the npm registry.
109+
110+
To install React 16 with Yarn, run:
111+
112+
```bash
113+
yarn add react@^16.8.0 react-dom@^16.8.0
114+
```
115+
116+
To install React 16 with npm, run:
117+
118+
```bash
119+
npm install --save react@^16.8.0 react-dom@^16.8.0
120+
```
121+
122+
We also provide UMD builds of React via a CDN:
123+
124+
```html
125+
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
126+
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
127+
```
128+
129+
Refer to the documentation for [detailed installation instructions](/docs/installation.html).
130+
131+
### ESLint Plugin for React Hooks
132+
133+
>Note
134+
>
135+
>As mentioned above, we strongly recommend using the `eslint-plugin-react-hooks` lint rule.
136+
>
137+
>If you're using Create React App, instead of manually configuring ESLint you can wait for the next version of `react-scripts` which will come out shortly and will include this rule.
138+
139+
Assuming you already have ESLint installed, run:
140+
141+
```sh
142+
# npm
143+
npm install eslint-plugin-react-hooks@next --save-dev
144+
145+
# yarn
146+
yarn add eslint-plugin-react-hooks@next --dev
147+
```
148+
149+
Then add it to your ESLint configuration:
150+
151+
```js
152+
{
153+
"plugins": [
154+
// ...
155+
"react-hooks"
156+
],
157+
"rules": {
158+
// ...
159+
"react-hooks/rules-of-hooks": "error"
160+
}
161+
}
162+
```
163+
164+
## Changelog
165+
166+
### React
167+
168+
* Add [Hooks](https://reactjs.org/docs/hooks-intro.html) — a way to use state and other React features without writing a class. ([@acdlite](https://github.com/acdlite) et al. in [#13968](https://github.com/facebook/react/pull/13968))
169+
* Improve the `useReducer` Hook lazy initialization API. ([@acdlite](https://github.com/acdlite) in [#14723](https://github.com/facebook/react/pull/14723))
170+
171+
### React DOM
172+
173+
* Bail out of rendering on identical values for `useState` and `useReducer` Hooks. ([@acdlite](https://github.com/acdlite) in [#14569](https://github.com/facebook/react/pull/14569))
174+
* Don’t compare the first argument passed to `useEffect`/`useMemo`/`useCallback` Hooks. ([@acdlite](https://github.com/acdlite) in [#14594](https://github.com/facebook/react/pull/14594))
175+
* Use `Object.is` algorithm for comparing `useState` and `useReducer` values. ([@Jessidhia](https://github.com/Jessidhia) in [#14752](https://github.com/facebook/react/pull/14752))
176+
* Support synchronous thenables passed to `React.lazy()`. ([@gaearon](https://github.com/gaearon) in [#14626](https://github.com/facebook/react/pull/14626))
177+
* Render components with Hooks twice in Strict Mode (DEV-only) to match class behavior. ([@gaearon](https://github.com/gaearon) in [#14654](https://github.com/facebook/react/pull/14654))
178+
* Warn about mismatching Hook order in development. ([@threepointone](https://github.com/threepointone) in [#14585](https://github.com/facebook/react/pull/14585) and [@acdlite](https://github.com/acdlite) in [#14591](https://github.com/facebook/react/pull/14591))
179+
* Effect clean-up functions must return either `undefined` or a function. All other values, including `null`, are not allowed. [@acdlite](https://github.com/acdlite) in [#14119](https://github.com/facebook/react/pull/14119)
180+
181+
### React Test Renderer
182+
183+
* Support Hooks in the shallow renderer. ([@trueadm](https://github.com/trueadm) in [#14567](https://github.com/facebook/react/pull/14567))
184+
* Fix wrong state in `shouldComponentUpdate` in the presence of `getDerivedStateFromProps` for Shallow Renderer. ([@chenesan](https://github.com/chenesan) in [#14613](https://github.com/facebook/react/pull/14613))
185+
* Add `ReactTestRenderer.act()` and `ReactTestUtils.act()` for batching updates so that tests more closely match real behavior. ([@threepointone](https://github.com/threepointone) in [#14744](https://github.com/facebook/react/pull/14744))
186+
187+
### ESLint Plugin: React Hooks
188+
189+
* Initial [release](https://www.npmjs.com/package/eslint-plugin-react-hooks). ([@calebmer](https://github.com/calebmer) in [#13968](https://github.com/facebook/react/pull/13968))
190+
* Fix reporting after encountering a loop. ([@calebmer](https://github.com/calebmer) and [@Yurickh](https://github.com/Yurickh) in [#14661](https://github.com/facebook/react/pull/14661))
191+
* Don't consider throwing to be a rule violation. ([@sophiebits](https://github.com/sophiebits) in [#14040](https://github.com/facebook/react/pull/14040))
192+
193+
## Hooks Changelog Since Alpha Versions
194+
195+
The above changelog contains all notable changes since our last **stable** release (16.7.0). [As with all our minor releases](/docs/faq-versioning.html), none of the changes break backwards compatibility.
196+
197+
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.
198+
199+
Here are all breaking changes to Hooks that have been made since the first alpha release:
200+
201+
* Remove `useMutationEffect`. ([@sophiebits](https://github.com/sophiebits) in [#14336](https://github.com/facebook/react/pull/14336))
202+
* Rename `useImperativeMethods` to `useImperativeHandle`. ([@threepointone](https://github.com/threepointone) in [#14565](https://github.com/facebook/react/pull/14565))
203+
* Bail out of rendering on identical values for `useState` and `useReducer` Hooks. ([@acdlite](https://github.com/acdlite) in [#14569](https://github.com/facebook/react/pull/14569))
204+
* Don’t compare the first argument passed to `useEffect`/`useMemo`/`useCallback` Hooks. ([@acdlite](https://github.com/acdlite) in [#14594](https://github.com/facebook/react/pull/14594))
205+
* Use `Object.is` algorithm for comparing `useState` and `useReducer` values. ([@Jessidhia](https://github.com/Jessidhia) in [#14752](https://github.com/facebook/react/pull/14752))
206+
* Render components with Hooks twice in Strict Mode (DEV-only). ([@gaearon](https://github.com/gaearon) in [#14654](https://github.com/facebook/react/pull/14654))
207+
* Improve the `useReducer` Hook lazy initialization API. ([@acdlite](https://github.com/acdlite) in [#14723](https://github.com/facebook/react/pull/14723))

content/docs/addons-test-utils.md

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm
1919

2020
> Nota:
2121
>
22+
<<<<<<< HEAD
2223
> Airbnb ha liberado una utilidad para pruebas llamada Enzyme, que hace fácil asegurar, manipular y navegar por el resultado de sus Componentes de React. Si está decidiendo que utilidad para pruebas unitarias utilizar junto con Jest u otra herramienta para pruebas, vale la pena darle un vistazo a: [http://airbnb.io/enzyme/](http://airbnb.io/enzyme/)
2324
>
2425
> Como otra opción, también hay otra utilidad para pruebas llamada react-testing-library diseñada para permitir e incentivar el escribir las pruebas de sus componentes de la misma forma en que los usuarios finales los usarían. De igual forma, funciona con cualquiera de los ejecutores de pruebas: [https://git.io/react-testing-library](https://git.io/react-testing-library)
26+
=======
27+
> We recommend using [`react-testing-library`](https://git.io/react-testing-library) which is designed to enable and encourage writing tests that use your components as the end users do.
28+
>
29+
> Alternatively, Airbnb has released a testing utility called [Enzyme](http://airbnb.io/enzyme/), which makes it easy to assert, manipulate, and traverse your React Components' output.
30+
>>>>>>> 98c1d22fbef2638cafb03b07e0eabe2a6186fca8
2531
26-
- [`Simulate`](#simulate)
27-
- [`renderIntoDocument()`](#renderintodocument)
32+
- [`act()`](#act)
2833
- [`mockComponent()`](#mockcomponent)
2934
- [`isElement()`](#iselement)
3035
- [`isElementOfType()`](#iselementoftype)
@@ -38,9 +43,12 @@ var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm
3843
- [`findRenderedDOMComponentWithTag()`](#findrendereddomcomponentwithtag)
3944
- [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype)
4045
- [`findRenderedComponentWithType()`](#findrenderedcomponentwithtype)
46+
- [`renderIntoDocument()`](#renderintodocument)
47+
- [`Simulate`](#simulate)
4148

4249
## Referencia
4350

51+
<<<<<<< HEAD
4452
## Renderizado superficial
4553

4654
Cuando se escriben pruebas de unidad para React, el renderizado superficial puede ser de ayuda. El renderizado superficial permite renderizar el componente "un nivel de profundidad" y asegurar lo que su método de renderizado retorna, sin preocuparse acerca del comportamiento de los componentes hijos, los cuales no son instanciados o renderizados. Esto no requiere de un DOM.
@@ -100,6 +108,89 @@ Renderiza un Elemento de React en un nodo separado del DOM en el documento. **Es
100108
> Nota:
101109
>
102110
> Necesitará tener `window`, `window.document` y `window.document.createElement` habilitados de forma global **antes** de importar `React`. De otro modo React pensará que no tiene acceso al DOM y los métodos como `setState` no funcionarán.
111+
=======
112+
### `act()`
113+
114+
To prepare a component for assertions, wrap the code rendering it and performing updates inside an `act()` call. This makes your test run closer to how React works in the browser.
115+
116+
>Note
117+
>
118+
>If you use `react-test-renderer`, it also provides an `act` export that behaves the same way.
119+
120+
For example, let's say we have this `Counter` component:
121+
122+
```js
123+
class App extends React.Component {
124+
constructor(props) {
125+
super(props);
126+
this.state = {count: 0};
127+
this.handleClick = this.handleClick.bind(this);
128+
}
129+
componentDidMount() {
130+
document.title = `You clicked ${this.state.count} times`;
131+
}
132+
componentDidUpdate() {
133+
document.title = `You clicked ${this.state.count} times`;
134+
}
135+
handleClick() {
136+
this.setState(state => ({
137+
count: state.count + 1,
138+
}));
139+
}
140+
render() {
141+
return (
142+
<div>
143+
<p>You clicked {this.state.count} times</p>
144+
<button onClick={this.handleClick}>
145+
Click me
146+
</button>
147+
</div>
148+
);
149+
}
150+
}
151+
```
152+
153+
Here is how we can test it:
154+
155+
```js{3,20-22,29-31}
156+
import React from 'react';
157+
import ReactDOM from 'react-dom';
158+
import { act } from 'react-dom/test-utils';
159+
import Counter from './Counter';
160+
161+
let container;
162+
163+
beforeEach(() => {
164+
container = document.createElement('div');
165+
document.body.appendChild(container);
166+
});
167+
168+
afterEach(() => {
169+
document.body.removeChild(container);
170+
container = null;
171+
});
172+
173+
it('can render and update a counter', () => {
174+
// Test first render and componentDidMount
175+
act(() => {
176+
ReactDOM.render(<Counter />, container);
177+
});
178+
const button = container.querySelector('button');
179+
const label = container.querySelector('p');
180+
expect(label.textContent).toBe('You clicked 0 times');
181+
expect(document.title).toBe('You clicked 0 times');
182+
183+
// Test second render and componentDidUpdate
184+
act(() => {
185+
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
186+
});
187+
expect(label.textContent).toBe('You clicked 1 times');
188+
expect(document.title).toBe('You clicked 1 times');
189+
});
190+
```
191+
192+
Don't forget that dispatching DOM events only works when the DOM container is added to the `document`. You can use a helper like [`react-testing-library`](https://github.com/kentcdodds/react-testing-library) to reduce the boilerplate code.
193+
>>>>>>> 98c1d22fbef2638cafb03b07e0eabe2a6186fca8
103194
104195
* * *
105196

@@ -265,4 +356,65 @@ findRenderedComponentWithType(
265356

266357
Igual a [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype) pero espera que sólo haya un resultado y retorna ese único resultado, de lo contrario lanza una excepción si hay algún otro número de coincidencias diferentes a una.
267358

359+
***
360+
361+
### `renderIntoDocument()`
362+
363+
```javascript
364+
renderIntoDocument(element)
365+
```
366+
367+
Render a React element into a detached DOM node in the document. **This function requires a DOM.** It is effectively equivalent to:
368+
369+
```js
370+
const domContainer = document.createElement('div');
371+
ReactDOM.render(element, domContainer);
372+
```
373+
374+
> Note:
375+
>
376+
> You will need to have `window`, `window.document` and `window.document.createElement` globally available **before** you import `React`. Otherwise React will think it can't access the DOM and methods like `setState` won't work.
377+
378+
* * *
379+
<<<<<<< HEAD
380+
=======
381+
382+
## Other Utilities
383+
384+
### `Simulate`
385+
386+
```javascript
387+
Simulate.{eventName}(
388+
element,
389+
[eventData]
390+
)
391+
```
392+
393+
Simulate an event dispatch on a DOM node with optional `eventData` event data.
394+
395+
`Simulate` has a method for [every event that React understands](/docs/events.html#supported-events).
396+
397+
**Clicking an element**
398+
399+
```javascript
400+
// <button ref={(node) => this.button = node}>...</button>
401+
const node = this.button;
402+
ReactTestUtils.Simulate.click(node);
403+
```
404+
405+
**Changing the value of an input field and then pressing ENTER.**
406+
407+
```javascript
408+
// <input ref={(node) => this.textInput = node} />
409+
const node = this.textInput;
410+
node.value = 'giraffe';
411+
ReactTestUtils.Simulate.change(node);
412+
ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});
413+
```
414+
415+
> Note
416+
>
417+
> You will have to provide any event property that you're using in your component (e.g. keyCode, which, etc...) as React is not creating any of these for you.
418+
268419
* * *
420+
>>>>>>> 98c1d22fbef2638cafb03b07e0eabe2a6186fca8

0 commit comments

Comments
 (0)