import { Callout } from 'nextra-theme-docs'
이 기능을 사용하시려면 최신 버전(≥ 1.0.0)으로 업그레이드하세요. 대부분의 경우에 캐시를 직접 _작성_하면 안 됩니다. 이는 SWR에 정의되지 않은 동작을 유발할 수 있습니다. 수동으로 키를 변경해야 하는 경우 SWR APIs 사용을 고려해 주세요.여기도 확인해보세요: [뮤테이션](/docs/mutation), [테스트 케이스 간 캐시 초기화](#reset-cache-between-test-cases).
기본적으로 SWR은 전역 캐시를 사용해 모든 컴포넌트 사이에 데이터를 저장하고 공유합니다. 하지만 SWRConfig
의 provider
옵션으로 이 동작을 커스터마이징 할 수도 있습니다.
캐시 공급자는 더 맞춤화된 저장소로 SWR을 활성화하기 위한 것입니다.
캐시 공급자는 다음 TypeScript 정의와 일치하는 Map과 유사한 객체입니다(swr
로부터 임포트할 수 있습니다).
interface Cache<Data> {
get(key: string): Data | undefined
set(key: string, value: Data): void
delete(key: string): void
}
예를 들어, JavaScript Map 인스턴스는 SWR을 위한 캐시 공급자로 직접 사용할 수 있습니다.
SWRConfig
의 provider
옵션은 캐시 공급자를 반환하는 함수를 받습니다. 그러면 공급자를 SWRConfig
경계 내의 모든 SWR hook에서 사용할 수 있습니다.
import useSWR, { SWRConfig } from 'swr'
function App() {
return (
<SWRConfig value={{ provider: () => new Map() }}>
<Page/>
</SWRConfig>
)
}
<Page/>
내의 모든 SWR hook은 Map 인스턴스로부터 읽고 씁니다. 또한 특정 사례에 대해 다른 캐시 공급자 구현을 사용할 수도 있습니다.
import { Cache } from '@components/diagrams/cache'
중첩된 경우, SWR hook은 상위 레벨의 캐시 공급자를 사용합니다. 상위 레벨의 캐시 공급자가 존재하지 않을 경우, 빈 Map
인 기본 캐시 공급자로 대체됩니다.
React 컴포넌트 내에 있을 때, mutate
를 포함해 다른 설정과 마찬가지로 현재 캐시 공급자에 접근하려면 useSWRConfig
hook을 사용해야 합니다.
import { useSWRConfig } from 'swr'
function Avatar() {
const { cache, mutate, ...extraConfig } = useSWRConfig()
// ...
}
<SWRConfig>
아래에 존재하지 않는다면 기본 설정을 반환합니다.
여러 <SWRConfig>
컴포넌트가 중첩되어 있을 때, 캐시 공급자를 확장할 수 있습니다.
provider
함수의 첫 번째 인자는 상위 레벨 <SWRConfig>
(또는 부모 <SWRConfig>
가 존재하지 않을 경우 기본 캐시)의 캐시 공급자입니다. 이를 사용해 캐시 공급자를 확장할 수 있습니다.
<SWRConfig value={{ provider: (cache) => newCache }}>
...
</SWRConfig>
캐시 공급자 API의 유연성으로, "부분 변경" 헬퍼를 구축할 수도 있습니다.
아래 예시에서는 matchMutate
가 정규 표현식을 키로 받고, 이 패턴에 일치하는 것들을 변경하는데 사용할 수 있습니다.
function useMatchMutate() {
const { cache, mutate } = useSWRConfig()
return (matcher, ...args) => {
if (!(cache instanceof Map)) {
throw new Error('matchMutate requires the cache provider to be a Map instance')
}
const keys = []
for (const key of cache.keys()) {
if (matcher.test(key)) {
keys.push(key)
}
}
const mutations = keys.map((key) => mutate(key, ...args))
return Promise.all(mutations)
}
}
그 후 여러분의 컴포넌트 내에서:
function Button() {
const matchMutate = useMatchMutate()
return <button onClick={() => matchMutate(/^\/api\//)}>
Revalidate all keys start with "/api/"
</button>
}
캐시를 localStorage
와 동기화하길 원할 수도 있습니다. 다음은 구현 예시입니다.
function localStorageProvider() {
// 초기화할 때, `localStorage`의 데이터를 map으로 복구합니다.
const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))
// app을 unloading하기 전에, 모든 데이터를 `localStorage`에 다시 씁니다.
window.addEventListener('beforeunload', () => {
const appCache = JSON.stringify(Array.from(map.entries()))
localStorage.setItem('app-cache', appCache)
})
// 성능을 위해 여전히 map을 사용해 쓰고 읽습니다.
return map
}
그 후 이를 공급자로서 사용합니다.
<SWRConfig value={{ provider: localStorageProvider }}>
<App/>
</SWRConfig>
애플리케이션을 테스트할 때, 테스트 케이스 간 SWR 캐시를 초기화하길 원할 수도 있습니다. 간단하게 빈 캐시 공급자로 애플리케이션을 감싸면 됩니다. 다음은 Jest를 사용한 예시입니다.
describe('test suite', async () => {
it('test case', async () => {
render(
<SWRConfig value={{ provider: () => new Map() }}>
<App/>
</SWRConfig>
)
})
})
알림: 캐시를 직접 쓰면 안 됩니다. 정의되지 않은 동작을 유발할 수도 있습니다.
const { cache } = useSWRConfig()
cache.get(key) // 키에 대한 현재 데이터 가져오기.
cache.clear() // ⚠️ 모든 캐시를 삭제하기. SWR은 다시 렌더링할 때 재검증합니다.