|
1 | 1 | import { act, screen, fireEvent } from '@testing-library/react' |
2 | | -import React from 'react' |
| 2 | +import React, { useEffect } from 'react' |
3 | 3 | import useSWR from 'swr' |
4 | 4 | import { |
5 | 5 | createResponse, |
@@ -77,6 +77,51 @@ describe('useSWR - loading', () => { |
77 | 77 | expect(dataLoaded).toEqual(true) |
78 | 78 | }) |
79 | 79 |
|
| 80 | + it('should avoid extra rerenders is the data is the `same`', async () => { |
| 81 | + let renderCount = 0, |
| 82 | + initialDataLoaded = false, |
| 83 | + mutationDataLoaded = false |
| 84 | + |
| 85 | + const key = createKey() |
| 86 | + function Page() { |
| 87 | + const { data, mutate } = useSWR( |
| 88 | + key, |
| 89 | + async () => { |
| 90 | + const res = await createResponse({ greeting: 'hello' }) |
| 91 | + initialDataLoaded = true |
| 92 | + return res |
| 93 | + }, |
| 94 | + { fallbackData: { greeting: 'hello' } } |
| 95 | + ) |
| 96 | + |
| 97 | + useEffect(() => { |
| 98 | + const timeout = setTimeout( |
| 99 | + () => |
| 100 | + mutate(async () => { |
| 101 | + const res = await createResponse({ greeting: 'hello' }) |
| 102 | + mutationDataLoaded = true |
| 103 | + return res |
| 104 | + }), |
| 105 | + 200 |
| 106 | + ) |
| 107 | + |
| 108 | + return () => clearTimeout(timeout) |
| 109 | + }, [mutate]) |
| 110 | + |
| 111 | + renderCount++ |
| 112 | + return <div>{data?.greeting}</div> |
| 113 | + } |
| 114 | + |
| 115 | + renderWithConfig(<Page />) |
| 116 | + screen.getByText('hello') |
| 117 | + |
| 118 | + await act(() => sleep(1000)) // wait |
| 119 | + // it doesn't re-render, but fetch was triggered |
| 120 | + expect(initialDataLoaded).toEqual(true) |
| 121 | + expect(mutationDataLoaded).toEqual(true) |
| 122 | + expect(renderCount).toEqual(1) |
| 123 | + }) |
| 124 | + |
80 | 125 | it('should return enumerable object', async () => { |
81 | 126 | // If the returned object is enumerable, we can use the spread operator |
82 | 127 | // to deconstruct all the keys. |
|
0 commit comments