Skip to content

Commit 779d025

Browse files
committed
Updated react hooks example page
1 parent 01dd2d7 commit 779d025

File tree

1 file changed

+34
-166
lines changed

1 file changed

+34
-166
lines changed

docs/example-react-hooks.md

Lines changed: 34 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
id: example-react-hooks
33
title: React Hooks
44
---
5-
6-
`react-testing-library` provides the
7-
[`testHook`](/docs/react-testing-library/api#testhook) utility to test custom
8-
hooks.
5+
[`react-hooks-testing-library`][gh] is built on top of [`react-testing-library`][gh] to create a simple test harness for [React hooks](https://reactjs.org/docs/hooks-intro.html) that handles running them within the body of a function component, as well as providing various useful utility functions for updating the inputs and retrieving the outputs of your [custom hook](https://reactjs.org/docs/hooks-custom.html).
96

107
> **Note**
118
>
@@ -14,189 +11,60 @@ hooks.
1411
> hooks. Typically those are better tested by testing the component that is
1512
> using it.
1613
17-
## Using `result`
18-
19-
Testing the last returned value of a hook using the `result` ref
20-
21-
```jsx
22-
function useCounter({ initialCount = 0, step = 1 } = {}) {
23-
const [count, setCount] = React.useState(initialCount)
24-
const increment = () => setCount(c => c + step)
25-
const decrement = () => setCount(c => c - step)
26-
return { count, increment, decrement }
27-
}
2814
```
29-
30-
```jsx
31-
test('returns result ref with latest result from hook execution', () => {
32-
const { result } = testHook(useCounter)
33-
expect(result.current.count).toBe(0)
34-
act(() => {
35-
result.current.increment()
36-
})
37-
expect(result.current.count).toBe(1)
38-
})
15+
npm install --save-dev react-hooks-testing-library
3916
```
4017

41-
## State
42-
43-
Testing a hook that provides state
44-
45-
```jsx
18+
```js
19+
// useCounter.js
4620
import { useState } from 'react'
4721

48-
export function useCounter({ initialCount = 0, step = 1 } = {}) {
22+
function useCounter(initialCount = 0) {
4923
const [count, setCount] = useState(initialCount)
50-
const increment = () => setCount(c => c + step)
51-
const decrement = () => setCount(c => c - step)
52-
return { count, increment, decrement }
24+
25+
const incrementBy = useCallback((n) => setCount(count + n), [count])
26+
const decrementBy = useCallback((n) => setCount(count - n), [count])
27+
28+
return { count, incrementBy, decrementBy }
5329
}
30+
31+
export default useCounter
5432
```
5533

56-
```jsx
57-
import { testHook, act, cleanup } from 'react-testing-library'
34+
```js
35+
// useCounter.test.js
36+
import { renderHook, cleanup, act } from 'react-hooks-testing-library'
37+
import useCounter from './useCounter'
38+
5839
afterEach(cleanup)
5940

60-
describe('useCounter', () => {
61-
test('accepts default initial values', () => {
62-
let count
63-
testHook(() => ({ count } = useCounter()))
64-
65-
expect(count).toBe(0)
66-
})
67-
68-
test('accepts a default initial value for `count`', () => {
69-
let count
70-
testHook(() => ({ count } = useCounter({})))
71-
72-
expect(count).toBe(0)
73-
})
74-
75-
test('provides an `increment` function', () => {
76-
let count, increment
77-
testHook(() => ({ count, increment } = useCounter({ step: 2 })))
78-
79-
expect(count).toBe(0)
80-
act(() => {
81-
increment()
82-
})
83-
expect(count).toBe(2)
84-
})
85-
86-
test('provides an `decrement` function', () => {
87-
let count, decrement
88-
testHook(() => ({ count, decrement } = useCounter({ step: 2 })))
89-
90-
expect(count).toBe(0)
91-
act(() => {
92-
decrement()
93-
})
94-
expect(count).toBe(-2)
95-
})
96-
97-
test('accepts a default initial value for `step`', () => {
98-
let count, increment
99-
testHook(() => ({ count, increment } = useCounter({})))
100-
101-
expect(count).toBe(0)
102-
act(() => {
103-
increment()
104-
})
105-
expect(count).toBe(1)
106-
})
41+
test('should create counter', () => {
42+
const { result } = renderHook(() => useCounter())
43+
44+
expect(result.current.count).toBe(0)
10745
})
108-
```
10946

110-
## Unmount Side-Effects
47+
test('should increment counter', () => {
48+
const { result } = renderHook(() => useCounter())
11149

112-
Using the `unmount` function to check useEffect behavior when unmounting
50+
act(() => result.current.incrementBy(1))
11351

114-
```jsx
115-
import { useState, useEffect } from 'react'
52+
expect(result.current.count).toBe(1)
11653

117-
export function useDocumentTitle(title) {
118-
const [originalTitle, setOriginalTitle] = useState(document.title)
119-
useEffect(() => {
120-
setOriginalTitle(document.title)
121-
document.title = title
122-
return () => {
123-
document.title = originalTitle
124-
}
125-
}, [title])
126-
}
127-
```
54+
act(() => result.current.incrementBy(2))
12855

129-
```jsx
130-
describe('useDocumentTitle', () => {
131-
test('sets a title', () => {
132-
document.title = 'original title'
133-
testHook(() => {
134-
useDocumentTitle('modified title')
135-
})
136-
137-
expect(document.title).toBe('modified title')
138-
})
139-
140-
test('returns to original title when component is unmounted', () => {
141-
document.title = 'original title'
142-
const { unmount } = testHook(() => {
143-
useDocumentTitle('modified title')
144-
})
145-
146-
unmount()
147-
expect(document.title).toBe('original title')
148-
})
56+
expect(result.current.count).toBe(3)
14957
})
150-
```
15158

152-
## Rerender Side-Effects
59+
test('should decrement counter', () => {
60+
const { result } = renderHook(() => useCounter())
15361

154-
Using the `rerender` function to test calling useEffect multiple times
62+
act(() => result.current.decrementBy(1))
15563

156-
```jsx
157-
import { useEffect } from 'react'
64+
expect(result.current.count).toBe(-1)
15865

159-
export function useCall(callback, deps) {
160-
useEffect(() => {
161-
callback()
162-
}, deps)
163-
}
164-
```
66+
act(() => result.current.decrementBy(2))
16567

166-
```jsx
167-
describe('useCall', () => {
168-
test('calls once on render', () => {
169-
const spy = jest.fn()
170-
testHook(() => {
171-
useCall(spy, [])
172-
})
173-
expect(spy).toHaveBeenCalledTimes(1)
174-
})
175-
176-
test('calls again if deps change', () => {
177-
let deps = [false]
178-
const spy = jest.fn()
179-
const { rerender } = testHook(() => {
180-
useCall(spy, deps)
181-
})
182-
expect(spy).toHaveBeenCalledTimes(1)
183-
184-
deps = [true]
185-
rerender()
186-
expect(spy).toHaveBeenCalledTimes(2)
187-
})
188-
189-
test('does not call again if deps are the same', () => {
190-
let deps = [false]
191-
const spy = jest.fn()
192-
const { rerender } = testHook(() => {
193-
useCall(spy, deps)
194-
})
195-
expect(spy).toHaveBeenCalledTimes(1)
196-
197-
deps = [false]
198-
rerender()
199-
expect(spy).toHaveBeenCalledTimes(1)
200-
})
68+
expect(result.current.count).toBe(-3)
20169
})
202-
```
70+
```

0 commit comments

Comments
 (0)