use-swr-laggy.test.tsx
Overview
The use-swr-laggy.test.tsx file contains a suite of automated tests for verifying the behavior of the useSWR and useSWRInfinite React hooks, specifically focusing on the keepPreviousData option. These hooks are part of the SWR (stale-while-revalidate) data fetching library commonly used in React applications.
The primary purpose of these tests is to ensure that when the keepPreviousData option is enabled:
The hook retains the previous key's data while fetching new data on key changes.
The cache sharing between multiple hooks behaves correctly.
The fallback data interacts properly with the laggy data feature.
The hook returns the latest data consistently.
The
useSWRInfinitehook supports keeping previous page data.Dynamically changing the
keepPreviousDataoption works as expected.The component re-renders correctly even when data and fallback data are the same.
The laggy data state behaves correctly even when the key does not change but the data mutates.
These tests use React Testing Library to simulate user interactions and lifecycle events, and verify the data states over time.
Detailed Explanation of Contents
Imports and Utilities Used
screen, act, fireEventfrom@testing-library/react: Utilities for querying DOM, batching updates, and simulating user events.useState from React: To manage state inside test components.
useSWR,useSWRInfinitefromswr: The hooks under test.Helper functions from ./utils including:
createKey(): Generates unique keys for SWR.createResponse(key, options): Returns a promise that resolves with the key after a delay.renderWithConfig(component): Renders components with the required SWR configuration.sleep(ms): Returns a promise that resolves after ms milliseconds.
Test Suites and Test Cases
All tests are wrapped in a top-level describe block titled 'useSWR - keep previous data'.
1. should keep previous data when key changes when keepPreviousData is enabled
Purpose: Verifies that when the key changes and
keepPreviousDatais enabled, the hook retains the previous data until new data is fetched.Implementation Details:
Uses useState to hold the current key.
Calls
useSWRwithkeepPreviousData: true.Logs the key and data on every render.
Simulates a button click to change the key.
Expected Behavior: The logged data array should show that on key change, the data does not become undefined immediately but keeps the previous data until the new data resolves.
2. should keep previous data when sharing the cache
Purpose: Tests cache sharing between two
useSWRhooks with and withoutkeepPreviousData.Implementation Details:
Two hooks use the same key and fetcher.
One hook has
keepPreviousDataenabled, the other does not.Both data values are logged.
Expected Behavior: The hook with
keepPreviousDataretains previous data when the key changes, while the other resets immediately.
3. should keep previous data even if there is fallback data
Purpose: Confirms that
keepPreviousDataworks correctly even when fallback data is provided.Implementation Details:
Both hooks receive a fallback value
'fallback'.One hook has
keepPreviousDataenabled.
Expected Behavior: On key change, the hook with
keepPreviousDataretains the previous fetched data rather than the fallback.
4. should always return the latest data
Purpose: Tests that the hook returns the most recent data, even after a mutate call.
Implementation Details:
Hook uses
keepPreviousData.Two buttons: one to change key, one to mutate data manually.
Expected Behavior: Data updates correctly after mutate, retaining previous data during loading phases.
5. should keep previous data for the useSWRInfinite hook
Purpose: Verifies
keepPreviousDatabehavior for theuseSWRInfinitehook.Implementation Details:
useSWRInfiniteis invoked with a function returning the current key.Data is an array of page data.
Expected Behavior: On key change, previous page data persists until new data is fetched.
6. should support changing the keepPreviousData option
Purpose: Tests dynamic toggling of the
keepPreviousDataoption between false andtrue.Implementation Details:
keepPreviousDatais controlled by a variable outside the component.Multiple key changes are triggered with toggled settings.
Expected Behavior: Data retention behavior matches the current value of
keepPreviousData.
7. should re-render when returned data and fallbackData is the same and keepPreviousData is enabled
Purpose: Ensures re-rendering occurs even if
dataandfallbackDataare equal, addressing a known issue.Implementation Details:
Uses two keys alternating on button click.
fallbackDatais static.revalidateOnMountandrevalidateOnFocusare disabled to control revalidation.
Expected Behavior: UI updates properly with each key change reflecting new data.
8. should work keepPreviousData without changing the key
Purpose: Checks that
keepPreviousDatabehaves correctly when the key remains the same, but the data is mutated.Implementation Details:
Expected Behavior: The laggy data retains the previous value while the new fetch is in progress.
Important Implementation Details and Algorithms
keepPreviousDataoption: This option allows SWR hooks to retain previous data during key changes or refetches, preventing flickering or empty states.Asynchronous fetch simulation: The tests use the
createResponsehelper with artificial delays to simulate network latency, important for verifying transitional states.Logging state snapshots: Each render logs the current key and data state into an array for later assertions, capturing the sequence of state changes over time.
Use of
actandsleep: Ensures React state updates and effects are flushed and asynchronous timeouts complete before assertions.Cache sharing: Tests demonstrate that multiple hooks sharing the same key and cache reflect consistent data states.
Interaction with Other Parts of the System
SW utilities (
createKey,createResponse,renderWithConfig,sleep): These helper functions abstract away complexity in key generation, mock data fetching, and rendering environment setup.useSWRanduseSWRInfinite: The hooks under test come from the SWR library, which manages caching, revalidation, and data fetching lifecycles.React Testing Library: Provides the framework for rendering components, simulating user events, and querying rendered output.
This test file is part of the SWR codebase or a related test suite, likely run as part of CI to validate hook behavior.
Usage Examples
Although this is a test file, the patterns exemplify how useSWR can be used with keepPreviousData:
import useSWR from 'swr'
function Example() {
const { data } = useSWR('/api/data', fetcher, { keepPreviousData: true })
return <div>{data ?? 'Loading...'}</div>
}
Changing the key (e.g., URL) will keep showing the old data until the new data arrives, improving UI stability.
Mermaid Diagram: Component and Function Flow
The file primarily contains test components inside test cases, each with a similar structure. The main relationships are between:
Test case → Test component → useSWR / useSWRInfinite hook → fetcher function
User actions (button clicks) trigger state changes → SWR refetches → component re-renders → logs data
flowchart TD
TestSuite["describe('useSWR - keep previous data')"]
subgraph TestCases
T1["it('should keep previous data when key changes')"]
T2["it('should keep previous data when sharing the cache')"]
T3["it('should keep previous data with fallback data')"]
T4["it('should always return latest data')"]
T5["it('should keep previous data for useSWRInfinite')"]
T6["it('should support changing keepPreviousData option')"]
T7["it('should re-render when data and fallbackData are same')"]
T8["it('should work keepPreviousData without key change')"]
end
subgraph Components
App1["App Component (T1)"]
App2["App Component (T2)"]
App3["App Component (T3)"]
App4["App Component (T4)"]
App5["App Component (T5)"]
App6["App Component (T6)"]
App7["App Component (T7)"]
App8["App Component (T8)"]
end
subgraph Hooks
useSWR1["useSWR with keepPreviousData"]
useSWR2["useSWR (normal)"]
useSWRInf["useSWRInfinite"]
end
subgraph Utilities
fetcher["fetcher (createResponse)"]
createKey["createKey()"]
render["renderWithConfig()"]
sleep["sleep()"]
end
TestSuite --> TestCases
T1 --> App1
T2 --> App2
T3 --> App3
T4 --> App4
T5 --> App5
T6 --> App6
T7 --> App7
T8 --> App8
App1 --> useSWR1
App2 --> useSWR1
App2 --> useSWR2
App3 --> useSWR1
App3 --> useSWR2
App4 --> useSWR1
App5 --> useSWRInf
App6 --> useSWR1
App7 --> useSWR1
App8 --> useSWR1
App8 --> useSWR2
useSWR1 --> fetcher
useSWR2 --> fetcher
useSWRInf --> fetcher
App1 --> createKey
App2 --> createKey
App3 --> createKey
App4 --> createKey
App5 --> createKey
App6 --> createKey
App7 --> -- keys array --
App8 --> createKey
TestCases --> render
TestCases --> sleep
Summary
File purpose: Automated tests for
useSWRanduseSWRInfinitehooks focusing onkeepPreviousDatabehavior.Core functionality: Verify that previous data is retained during key changes or mutations, preventing UI flicker and improving UX.
Key concepts: Data caching, laggy data pattern, fallback data integration, revalidation control.
Testing techniques: Controlled async fetching, state logging, simulated user interactions.
System integration: Works with SWR's internal cache and React component lifecycle, tested via React Testing Library.
This test file is critical to ensure the robustness and user experience quality of SWR's laggy data feature during asynchronous data fetching and key transitions.