Skip to content

Conversation

@Danny-Devs
Copy link

@Danny-Devs Danny-Devs commented May 20, 2025

Hello swrv team! I was examining issue #41 and thought that I'd be able to submit a solution for it--here it is.
Do note that I have utilized Claude 3.7 Sonnet through much of this process. I reviewed the code already, so I thought I'd create a PR for it so others can review it.

I've implemented comprehensive unit tests for this feature. I plan to test with the example applications in the repo as a follow-up to verify real-world behavior.

Looking forward to your feedback,

  • Danny

Add compare option for smarter data change detection

Overview

This PR implements a custom data comparison mechanism, allowing developers to precisely control when components re-render based on data changes. It also upgrades the default comparison to use dequal/lite, providing more intuitive deep equality checks.

Problem Solved

Without a custom compare option, swrv must re-render components whenever a new object reference is returned from a fetcher, even if the actual data content is identical. This leads to unnecessary re-renders when:

  • Two objects have the same logical content but different references
  • Objects differ only in fields that don't affect UI (timestamps, metadata, etc.)
  • Applications need domain-specific comparison logic

Implementation

The implementation is straightforward and minimally invasive:

  • Added dequal/lite as a dependency for efficient deep equality comparison
  • Extended the IConfig interface with a compare function option
  • Modified mutate to use this function for data change detection
  • Preserved backward compatibility with existing behavior

Benefits

This improvement enables several key use cases:

  • Performance optimization: Prevent unnecessary re-renders when only metadata changes
  • Semantic equality: Define custom equality logic for application-specific data structures
  • Selective field comparison: Ignore certain fields like timestamps or calculated values
  • Enhanced developer control: Fine-tune when components update for optimal UX

Example Usage

// Only re-render when name or id changes, ignore other fields
const { data } = useSWRV('/api/user', fetcher, {
  compare: (oldData, newData) => {
    if (!oldData || !newData) return oldData === newData
    return oldData.id === newData.id && oldData.name === newData.name
  }
})

Testing

Added comprehensive tests verifying:

  • Default dequal behavior prevents unnecessary updates for identical data
  • Custom comparison functions override default behavior as expected
  • Edge cases are handled correctly

Compatibility

Maintains 100% backward compatibility with existing code. The default behavior is improved but semantically equivalent for most use cases.

Resolves #41

- Introduced a `compare` option in the configuration to allow custom data comparison logic.
- Updated README to document the new feature and provide usage examples.
- Added `dequal` library as a dependency for deep equality checks.
- Modified relevant types and functions to support the new comparison feature.
- Implemented tests to verify default and custom comparison logic in the `useSWRV` hook.
- Added scenarios for deep equality checks, updates on data changes, and edge cases handling.
- Ensured that the comparison function behaves correctly under various conditions.
- Added "packageManager" field to package.json to specify the version of yarn being used.
- Updated useSWRV hook to include the custom comparison function in mutate calls for improved data handling.
@netlify
Copy link

netlify bot commented May 20, 2025

👷 Deploy request for docs-swrv pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 1bc2ee1

@CLAassistant
Copy link

CLAassistant commented May 20, 2025

CLA assistant check
All committers have signed the CLA.

- Added a comprehensive test suite for the custom data comparison feature in the `useSWRV` hook.
- Included tests for default dequal behavior, custom compare function scenarios, and edge cases handling.
- Ensured robust verification of component re-renders based on data changes, including special values and circular references.
- Eliminated the test case that checked for error handling when the compare function throws an error, as the current implementation of swrv does not support this feature.
- Updated comments to reflect the removal and clarify the focus of the remaining tests on valid comparison scenarios.
@Danny-Devs
Copy link
Author

Just @'ing folks in case that helps with visibility (lmk if this is bad practice and I won't do it again!) @adamdehaven @darrenjennings

@adamdehaven
Copy link
Member

Our team can take a look in the coming weeks - thanks for the submission

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add comparison of data via compare config

3 participants