With useSWR how can I compare data before and after revalidation?

144 Views Asked by At

Using Next.js and through useSWR I am pulling data from an endpoint every 30s using an automatic revalidation interval (https://swr.vercel.app/docs/revalidation#revalidate-on-interval). In the data that is being pulled, there is an array that on every pull will have between 1-4 more items since the last pull. How can I get the previous array.length and compare it to the new, revalidated array.length so that I have a variable that counts the differential?

The idea is to have the new items show up in an interval within those 30s. Suppose I have the array as 'messages', this is what I came to:

const prevMessagesLength = ?
const [message, setMessage] = useState(messages[0])
useEffect(() => {
        let length = messages.length - prevMessagesLength
        let delay = (30 / length) * 1000
        for (var i = length; i >= 0; i--) {
            showMessage(i)
        }
        function showMessage(i) {
            setTimeout(function () {
                setMessage(messages[i])
            }, (length - i) * delay)
        }
}, [messages])
1

There are 1 best solutions below

3
On

https://swr.vercel.app/docs/api

Based on the offical document of swr, there's an option 'compare(a,b)' on useSWR hook.

comparison function used to detect when returned data has changed, to avoid spurious rerenders. By default, stable-hash is used.

This option is origianlly for comparing existing data and new data, the point is that you can access both data in this compare function.

I think you could use like this below

import useSWR from 'swr';

const fetchData = async () => {
    // Your data fetching logic here
};

const MyComponent = () => {
    const [differenceCount, setDifferenceCount] = useState(0);

    const compareFunction = (prevData, newData) => {
        // Implement your logic to count differences
        const diffCount = calculateDifferences(prevData, newData);
        setDifferenceCount(diffCount);

        // Return true if data is different, otherwise false
        return diffCount > 0;
    };

    const { data, error } = useSWR('api/data', fetchData, {
        compare: compareFunction
    });

    const calculateDifferences = (prevData, newData) => {
        // Your logic to calculate the number of differences
        // This will depend on the structure of your data
    };

    if (error) return <div>Failed to load</div>;
    if (!data) return <div>Loading...</div>;

    return (
        <div>
            <p>Difference Count: {differenceCount}</p>
            {/* Render your component */}
        </div>
    );
};