Skip to content

Commit 2331b51

Browse files
author
pierrezimmermann
committed
docs: add documentation on renderhook
1 parent fe87a08 commit 2331b51

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

website/docs/API.md

+134
Original file line numberDiff line numberDiff line change
@@ -465,3 +465,137 @@ expect(submitButtons).toHaveLength(3); // expect 3 elements
465465
## `act`
466466

467467
Useful function to help testing components that use hooks API. By default any `render`, `update`, `fireEvent`, and `waitFor` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/main/packages/react-test-renderer/src/ReactTestRenderer.js#L567]).
468+
469+
## `renderHook`
470+
471+
function renderHook(callback: (props?: any) => any, options?: RenderHookOptions): RenderHookResult
472+
473+
Renders a test component that will call the provided `callback`, including any hooks it calls, every time it renders.
474+
475+
The `renderHook` function accepts the following arguments:
476+
477+
### `callback`
478+
479+
The function that is called each `render` of the test component. This function should call one or more hooks for testing.
480+
481+
The `props` passed into the callback will be the `initialProps` provided in the `options` to `renderHook`, unless new props are provided by a subsequent `rerender` call.
482+
483+
### `options` (Optional)
484+
485+
An options object to modify the execution of the `callback` function. See the `renderHook` Options section bellow for more details.
486+
487+
## `renderHook` Options
488+
489+
The `renderHook` function accepts the following options as the second parameter:
490+
491+
### `initialProps`
492+
493+
The initial values to pass as `props` to the `callback` function of `renderHook`.
494+
495+
### `wrapper`
496+
497+
A React component to wrap the test component in when rendering. This is usually used to add context providers from `React.createContext` for the hook to access with `useContext`. `initialProps` and props subsequently set by `rerender` will be provided to the wrapper.
498+
499+
## `renderHook` Result
500+
501+
The `renderHook` function returns an object that has the following properties:
502+
503+
### `result`
504+
505+
```jsx
506+
{
507+
all: Array<any>
508+
current: any,
509+
error: Error
510+
}
511+
```
512+
513+
The `current` value of the `result` will reflect the latest of whatever is returned from the `callback` passed to `renderHook`. Any thrown values from the latest call will be reflected in the `error` value of the `result`. The `all` value is an array containing all the returns (including the most recent) from the callback. These could be `result` or an `error` depending on what the callback returned at the time.
514+
515+
### `rerender`
516+
517+
function rerender(newProps?: any): void
518+
519+
A function to rerender the test component, causing any hooks to be recalculated. If `newProps` are passed, they will replace the `callback` function's `initialProps` for subsequent rerenders.
520+
521+
### `unmount`
522+
523+
function unmount(): void
524+
525+
A function to unmount the test component. This is commonly used to trigger cleanup effects for `useEffect` hooks.
526+
527+
## `Examples`
528+
529+
### `Basic example`
530+
531+
```jsx
532+
const useCount = () => {
533+
const [count, setCount] = useState(0);
534+
const increment = () => setCount(previousCount => previousCount + 1);
535+
536+
return { count, increment };
537+
}
538+
539+
it('should increment count', () => {
540+
const { result } = renderHook(() => useCount());
541+
542+
expect(result.current.count).toBe(0);
543+
544+
act(() => {
545+
result.increment()
546+
}
547+
548+
expect(result.current.count).toBe(1);
549+
}
550+
```
551+
552+
Note that you should wrap the calls to functions your hook returns with act if they trigger an update of your hook's state to ensure pending useEffects are run before your next assertion.
553+
554+
#### `With initial Props`
555+
556+
```jsx
557+
const useCount = (initialCount: number) => {
558+
const [count, setCount] = useState(initialCount);
559+
const increment = () => setCount(previousCount => previousCount + 1);
560+
561+
useEffect(() => {
562+
setCount(initialCount)
563+
}, [initialCount]);
564+
565+
return { count, increment };
566+
}
567+
568+
569+
570+
it('should increment count', () => {
571+
const { result, rerender } = renderHook((initialCount: number) => useCount(initialCount),
572+
{ initialProps: 1});
573+
574+
expect(result.current.count).toBe(1);
575+
576+
act(() => {
577+
result.increment()
578+
}
579+
580+
expect(result.current.count).toBe(2);
581+
582+
rerender(5);
583+
584+
expect(result.current.count).toBe(5);
585+
}
586+
```
587+
588+
### `With wrapper`
589+
590+
```jsx
591+
592+
it('should work properly', () => {
593+
function Wrapper({ children }: { children: ReactNode }) {
594+
return <Context.Provider value="provided">{children}</Context.Provider>;
595+
}
596+
597+
const { result } = renderHook(() => useHook(), { wrapper : Wrapper }
598+
599+
...
600+
}
601+
```

0 commit comments

Comments
 (0)