vercel / swr-site

The official website for SWR.
https://swr.vercel.app
Apache License 2.0
481 stars 351 forks source link

Feedback for “Cache” #573

Open CannonLock opened 5 months ago

CannonLock commented 5 months ago

When using the guide to make a LocalStorage Based Persistent Cache I am running into issues with the localStorageProvider running on the server resulting in errors. It would be nice for this document to elaborate on how to prevent this.

  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@mui/icons-material": "^5.14.3",
    "@mui/material": "^5.14.5",
    "@mui/x-date-pickers": "^6.16.0",
    "@types/node": "20.4.5",
    "@types/react": "18.2.16",
    "@types/react-dom": "18.2.7",
    "chart.js": "^4.4.0",
    "chartjs-adapter-luxon": "^1.3.1",
    "chartjs-plugin-zoom": "^2.0.1",
    "eslint": "8.45.0",
    "eslint-config-next": "13.4.12",
    "lodash": "^4.17.21",
    "luxon": "^3.4.3",
    "next": "14.0.3",
    "react": "18.2.0",
    "react-chartjs-2": "^5.2.0",
    "react-dom": "18.2.0",
    "swagger-ui-react": "^5.10.3",
    "swr": "^2.2.5",
    "typescript": "5.1.6",
    "yaml": "^2.3.4",
    "@next/bundle-analyzer": "^14.1.4"
  },
  "devDependencies": {
    "@types/lodash": "^4.14.202",
    "@types/luxon": "^3.3.2",
    "@types/swagger-ui-react": "^4.18.3"
  },
  "engines": {
    "node": "20"
  }
 ⨯ context/SWRConfigProvider.tsx (10:35) @ localStorage
 ⨯ ReferenceError: localStorage is not defined
    at localStorageProvider (./context/SWRConfigProvider.tsx:12:36)
    at provider (./context/SWRConfigProvider.tsx:25:27)
   8 |
   9 |     // When initializing, we restore the data from `localStorage` into a map.
> 10 |     const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))
     |                                   ^
  11 |
  12 |     // Before unloading the app, we write back all the data into `localStorage`.
  13 |     window.addEventListener('beforeunload', () => {
'use client'

import {ReactElement, useEffect, useState} from "react";
import { SWRConfig, Cache } from 'swr'

function localStorageProvider(): Cache<any> {

    // When initializing, we restore the data from `localStorage` into a map.
    const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))

    // Before unloading the app, we write back all the data into `localStorage`.
    window.addEventListener('beforeunload', () => {
        const appCache = JSON.stringify(Array.from(map.entries()))
        localStorage.setItem('app-cache', appCache)
        console.log("Saved Cache", map)
    })

    // We still use the map for write & read for performance.
    return map as Cache<any>
}

const SWRConfigProvider = ({children} : {children: ReactElement[] | ReactElement}) => {

    return (
        <SWRConfig value={{ provider: localStorageProvider }}>
            {children}
        </SWRConfig>
    )
}

export default SWRConfigProvider;