Reuse Cached Data For Rendering

Reusing Cached Data

RelayλŠ” app이 μ‚¬μš©λ˜λŠ” λ™μ•ˆ λ°œμƒν•œ μ—¬λŸ¬λ²ˆμ˜ 쿼리에 μ˜ν•΄ 받아와진 데이터듀을 μΆ•μ μ‹œν‚€κ³  캐싱해둔닀. 그리고 μ’…μ’… μš°λ¦¬λŠ” λ„€νŠΈμ›Œν¬λ₯Ό 톡해 데이터λ₯Ό μƒˆλ‘œ λ°›μ•„μ˜€μ§€ μ•Šκ³  μ΄λ ‡κ²Œ μΊμ‹±λœ 데이터λ₯Ό μ‚¬μš©ν•˜κΈΈ 원할 λ•Œκ°€ μžˆλ‹€.

μ•„λž˜ 상황듀이 μ΄λ ‡κ²Œ β€˜μΊμ‹±λœ 데이터’λ₯Ό μ΄μš©ν• λ§Œν•œ μ˜ˆμ‹œμ΄λ‹€.

  • μ•± λ‚΄μ˜ νƒ­λ“€ 사이λ₯Ό 이동할 λ•Œ, 그리고 κ·Έ 탭듀을 이동할 λ•Œ 데이터λ₯Ό 받아와야 ν•˜λŠ” κ²½μš°μ— 이미 ν•œ 번 λ°©λ¬Έν•œ 적이 μžˆλŠ” 탭은 μΊμ‹±λœ 데이터λ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— λ‹€μ‹œ λ„€νŠΈμ›Œν¬ μš”μ²­μ΄ λ°œμƒν•˜μ§€ μ•ŠμŒ.

  • ν•œλ²ˆ ν”Όλ“œμ— λ Œλ”λ§λœ 적이 μžˆλŠ” ν¬μŠ€νŠΈμ— λ‹€μ‹œ μ ‘κ·Όν•˜λ € ν•˜λŠ” 경우, 포슀트의 permalink νŽ˜μ΄μ§€λŠ” μΊμ‹œλ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— μ¦‰μ‹œ λ Œλ”λ§ 됨.

    • λ§Œμ•½ 포슀트의 permalink νŽ˜μ΄μ§€μ—μ„œ μ§€κΈˆ localμ—μ„œ κ°–κ³ μžˆλŠ” 것보닀 더 λ§Žμ€ 데이터λ₯Ό ν•„μš”λ‘œ ν•˜λ”λΌλ„, λ‹Ήμž₯은 κ°–κ³ μžˆλŠ” 데이터λ₯Ό μ‚¬μš©ν•˜κ³  λ Œλ”λ§μ„ blockμ‹œν‚€μ§€ μ•ŠμŒ.

Fetch Policies

μΊμ‹œλœ 데이터λ₯Ό μž¬μ‚¬μš©ν•˜λŠ” 방법은 loadQuery ν•¨μˆ˜ 내뢀에 fetchPolicy μ˜΅μ…˜μ„ μΆ”κ°€ν•˜λŠ” 것이닀. (이 loadQuery ν•¨μˆ˜λŠ” useQueryLoader 훅에 μ˜ν•΄ λ°˜ν™˜λœ ν•¨μˆ˜λ₯Ό 의미)

const React = require('React');
const {graphql} = require('react-relay');

function AppTabs() {
  const [
    queryRef,
    loadQuery,
  ] = useQueryLoader<HomeTabQueryType>(HomeTabQuery);

  const onSelectHomeTab = () => {
    loadQuery({id: '4'}, {fetchPolicy: 'store-or-network'});
  }

  // ...
}
  • useQueryLoader 훅에 μ˜ν•΄ λ°˜ν™˜λœ loadQuery ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ μ˜΅μ…˜μœΌλ‘œ fetchPolicy λ₯Ό μΆ”κ°€ν–ˆλ‹€. store-or-network μ˜΅μ…˜μ„ 쀬기 λ•Œλ¬Έμ— λ¨Όμ € μΊμ‹œ 데이터λ₯Ό ν™•μΈν•˜κ³ , 데이터가 μ—†λŠ” κ²½μš°μ—λ§Œ μƒˆλ‘œμš΄ 데이터λ₯Ό fetchν•˜λ„λ‘ ν•œλ‹€.

  • fetchPolicy λŠ” λ‹€μŒ λ‚΄μš©λ“€μ„ κ²°μ •ν•œλ‹€.

    • 둜컬 μΊμ‹œμ—μ„œ 데이터λ₯Ό μ‚¬μš©ν• μ§€

    • store(μΊμ‹œ)에 μžˆλŠ” λ°μ΄ν„°μ˜ κ°€μš© 여뢀에 따라 μ„œλ²„μ—μ„œ 데이터λ₯Ό fetch할지

기본적으둜, RelayλŠ” 둜컬 μΊμ‹œμ— μžˆλŠ” 쿼리λ₯Ό 읽어 데이터λ₯Ό κ°€μ Έμ˜€λ € ν•œλ‹€. ν•˜μ§€λ§Œ κ·Έ 쿼리에 λŒ€ν•œ 데이터가 μ—†κ±°λ‚˜ μ—…λ°μ΄νŠΈκ°€ ν•„μš”ν•  κ²½μš°μ—λŠ” 쿼리λ₯Ό 톡해 λ„€νŠΈμ›Œν¬ μš”μ²­μ„ 보내 전체 데이터λ₯Ό λ‹€μ‹œ κ°€μ Έμ˜¨λ‹€. μœ„μ— μžˆλŠ” store-or-network μ˜΅μ…˜μ€ 사싀 Relay의 κΈ°λ³Έ μ˜΅μ…˜μ΄λ‹€.

μ•„λž˜μ™€ 같은 λ‹€λ₯Έ μ˜΅μ…˜λ“€λ„ μžˆλ‹€.

  • store-and-network : 둜컬 μΊμ‹œμ˜ 데이터λ₯Ό 일단 μ“°μ§€λ§Œ, 항상 λ„€νŠΈμ›Œν¬ μš”μ²­μ„ λ‹€μ‹œ 보냄. 데이터가 μžˆλ“  μ—†λ“ , μ΅œμ‹ μ˜ 것이든 μ•„λ‹ˆλ“  상관 μ—†μŒ.

  • network-only : 둜컬 μΊμ‹œμ˜ 데이터λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  항상 λ„€νŠΈμ›Œν¬ μš”μ²­μ„ 톡해 μƒˆλ‘œ 받은 데이터λ₯Ό 이용.

  • store-only : 였직 둜컬 μΊμ‹œμ˜ λ°μ΄ν„°λ§Œ μž¬μ‚¬μš©ν•¨. λ„€νŠΈμ›Œν¬ μš”μ²­μ€ 보내지 μ•ŠμŒ. 이 λ•Œλ¬Έμ— 데이터 일관성에 λŒ€ν•œ μ±…μž„μ€ κ°œλ°œμžμ—κ²Œ 있음.

Availability of Data

RelayλŠ” 데이터가 β€˜κ°€μš©ν•œμ§€β€™μ— λŒ€ν•΄ 두가지 척도λ₯Ό 톡해 νŒλ‹¨ν•œλ‹€.

  1. Presence of Data

  2. Staleness of Data

Presence of Data

Relay store에 μžˆλŠ” λ°μ΄ν„°λŠ” 수λͺ…이 μžˆλŠ”λ°, 이 수λͺ…은 데이터가 κ°€μš©ν•œμ§€λ₯Ό νŒλ‹¨ν•  수 μžˆλŠ” μ€‘μš”ν•œ 척도이닀. 보톡 Relay store μ•ˆμ— μžˆλŠ” λ°μ΄ν„°λŠ” 첫 fetch 이후 계속 μ‘΄μž¬ν•œλ‹€. λ§Œμ•½ ν•œλ²ˆλ„ fetchν•œ 적이 μ—†λŠ” 데이터라면 storeμ—λŠ” μ‘΄μž¬ν•˜μ§€ μ•Šμ„ 것이닀.

그치만 μˆ˜λ§Žμ€ 쿼리듀을 톡해 κ°€μ Έμ˜¨ 데이터듀을 μ „λΆ€ λ©”λͺ¨λ¦¬μ— μ €μž₯ν•΄λ‘˜ μˆ˜λŠ” μ—†λ‹€. μ „λΆ€ μ €μž₯ν•΄λ‘”λ‹€λ©΄ μš°λ¦¬λŠ” λΆˆν•„μš”ν•˜κ²Œ λ°©λŒ€ν•˜κ³  낑은 데이터λ₯Ό μœ„ν•΄ λ§Žμ€ λ©”λͺ¨λ¦¬ 곡간을 λ‚­λΉ„ν•˜κ²Œ 될 것이닀.

이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ RelayλŠ” Garbage Collector라고 ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό λŒλ¦°λ‹€. 그러면 더 이상 쓰지 μ•ŠλŠ” 데이터듀을 μ‚­μ œν•  수 있게 λœλ‹€.

Garbage Collection in Relay

RelayλŠ” 특히 둜컬 in-memory storeμ—μ„œ Garbage Collection을 μˆ˜ν–‰ν•œλ‹€. μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈμ—κ²Œλ„ μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” 데이터듀을 μ‚­μ œν•œλ‹€.

그치만 데이터λ₯Ό μž¬μ‚¬μš©ν•  κ°€λŠ₯성도 염두에 둬야 ν•œλ‹€. λ§Œμ•½ 데이터가 λ„ˆλ¬΄ 빨리 μ‚­μ œλΌμ„œ μž¬μ‚¬μš©ν•˜λ €κ³  λ³΄λ‹ˆ μ—†λŠ” κ²½μš°μ—” λ„€νŠΈμ›Œν¬λ‘œλΆ€ν„° λ‹€μ‹œ 데이터λ₯Ό 받아와야 ν•˜κΈ° λ•Œλ¬Έμ— λ°”λ‘œ μž¬μ‚¬μš©ν•  수 μ—†κ²Œ λœλ‹€. κ·Έλž˜μ„œ μž¬μ‚¬μš©μ΄ 일어날 데이터듀은 ν™•μ‹€ν•˜κ²Œ β€˜μž¬μ‚¬μš© 할거닀’라고 λ§ν•΄μ£ΌλŠ” μž‘μ—…μ΄ ν•„μš”ν•˜λ‹€.

Query Retention

쿼리λ₯Ό μœ μ§€ν•œλ‹€λŠ” 것은 Relayμ—κ²Œ 쿼리와 쿼리에 κ΄€λ ¨λœ 데이터λ₯Ό μ§€μš°μ§€ 말아달라고 μ–˜κΈ°ν•˜λŠ”κ²ƒκ³Ό κ°™λ‹€. ν•˜λ‚˜ μ΄μƒμ˜ callerκ°€ μžˆλ‹€λ©΄ μΏΌλ¦¬λŠ” storeμ—μ„œ μ§€μ›Œμ§€μ§€ μ•Šκ²Œ λœλ‹€.

기본적으둜, 쿼리 μ»΄ν¬λ„ŒνŠΈλŠ” useQueryLoader λ‚˜ usePreloadQuery, ν˜Ήμ€ λ‹€λ₯Έ APIλ₯Ό μ‚¬μš©ν•œλ‹€. 쿼리 μ»΄ν¬λ„ŒνŠΈλŠ” mount 된 이후 쿼리λ₯Ό μœ μ§€ν•˜κ³ , unmount 된 이후 쿼리λ₯Ό 놓아쀀닀. 즉 unmount μ΄ν›„μ—λŠ” μ–Έμ œλΌλ„ storeμ—μ„œ 쿼리와 쿼리 κ΄€λ ¨ 데이터듀이 μ‚­μ œλ  수 μžˆλ‹€.

λ§Œμ•½ μ»΄ν¬λ„ŒνŠΈ 생λͺ…주기와 관계 없이 쿼리λ₯Ό μœ μ§€ν•˜κ³  μ‹Άλ‹€λ©΄, retain λ©”μ†Œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ λœλ‹€.

// Retain query; this will prevent the data for this query and
// variables from being garbage collected by Relay
const disposable = environment.retain(queryDescriptor);

// Disposing of the disposable will release the data for this query
// and variables, meaning that it can be deleted at any moment
// by Relay's garbage collection if it hasn't been retained elsewhere
disposable.dispose();
  • retain λ©”μ†Œλ“œλ₯Ό 톡해 쿼리 μ»΄ν¬λ„ŒνŠΈμ˜ 생λͺ…μ£ΌκΈ°μ™€λŠ” 상관 없이 쿼리λ₯Ό μœ μ§€ν•  수 μžˆλ‹€. 그러면 이후에 λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈκ°€ μž¬μ‚¬μš©ν•˜κ±°λ‚˜, μ§€κΈˆμ€ μ—†μ§€λ§Œ λ‚˜μ€‘μ— 생길 같은 μ»΄ν¬λ„ŒνŠΈμ˜ λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€κ°€ μž¬μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

  • dispose λ©”μ†Œλ“œλŠ” retain λ©”μ†Œλ“œμ™€ λ°˜λŒ€λ‘œ μž‘λ™ν•œλ‹€. μ–Έμ œλ“ μ§€ garbage collectionκ°€ 쿼리λ₯Ό 없앨 수 μžˆλ‹€.

Controlling Relay’s Garbage Collection Policy

ν˜„μž¬ Garbage Collection을 컨트둀 ν•  수 μžˆλŠ” μ˜΅μ…˜μ΄ 두가지 정도 μžˆλ‹€.

  • GC Scheduler

    gcScheduler λΌλŠ” ν•¨μˆ˜λ₯Ό Relay Store에 λΆ™μ—¬μ„œ Garbage Collection을 μŠ€μΌ€μ€„λ§ ν•  수 μžˆλ‹€.

    // Sample scheduler function
    // Accepts a callback and schedules it to run at some future time.
    function gcScheduler(run: () => void) {
      resolveImmediate(run);
    }
    
    const store = new Store(source, {gcScheduler});
    • μ›λž˜λŠ” μƒˆ Storeλ₯Ό 생성할 λ•Œ gcScheduler λ₯Ό 같이 주지 μ•ŠλŠ”λ‹€. κ·Έλž˜μ„œ RelayλŠ” resolveImmediate() ν•¨μˆ˜λ₯Ό 톡해 garbage collection을 μˆ˜ν–‰.

      • resolveImmediateλŠ” μ°Έμ‘°κ°€ λŠμ–΄μ‘Œμ„ λ•Œ λ°”λ‘œ garbage collection이 μˆ˜ν–‰λ˜λ„λ‘ ν•˜λŠ” μ •μ±….

      • κ·Έλž˜μ„œ 일단 μœ„ μ½”λ“œλŠ” 사싀상 gcScheduler μ˜΅μ…˜μ„ 주지 μ•Šμ€κ²ƒκ³Ό κ°™μŒ.

    • scheduler function을 톡해 garbage collection이 κΈ°λ³Έ μ˜΅μ…˜λ³΄λ‹€ 덜 곡격적으둜 μˆ˜ν–‰λ˜λ„λ‘ μž‘μ„±ν•  μˆ˜λ„ 있음. μ‹œκ°„μ΄λ‚˜ scheduler μ†μ„±μ΄λ‚˜ κ·Έ 외에 λ‹€λ₯Έ νœ΄λ¦¬μŠ€ν‹±λ“€μ„ μ΄μš©ν•˜λ©΄ 됨.

      • ν•¨μˆ˜μ˜ κ΅¬ν˜„λΆ€μ—μ„œ run μ½œλ°±μ„ μ¦‰μ‹œ μ‹€ν–‰ν•˜λ©΄ μ•ˆλ¨.

Garbage Collector Buffer Size

Relay StoreλŠ” λ‚΄λΆ€μ μœΌλ‘œ release bufferλ₯Ό κ°–κ³  μžˆλ‹€. 쿼리 μœ μ§€λž‘μ€ 상관 없이 λͺ‡ 개의 쿼리λ₯Ό μž„μ‹œλ‘œ μ €μž₯ν•œλ‹€. (λͺ‡ 개의 쿼리λ₯Ό μ €μž₯ν• μ§€λŠ” 쑰절이 κ°€λŠ₯) 쿼리λ₯Ό μ›λž˜ μ†Œμœ ν•˜λ˜ 쿼리 μ»΄ν¬λ„ŒνŠΈκ°€ unmount λ˜λŠ” λ“±μ˜ 이유둜 쿼리가 없어지더라도 일단은 release buffer에 λ‚¨λŠ”λ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ 이전 νŽ˜μ΄μ§€λ‘œ λŒμ•„κ°€κ±°λ‚˜ 이전 νƒ­μœΌλ‘œ λŒμ•„κ°ˆ λ•Œ 데이터λ₯Ό μž¬μ‚¬μš©ν•  수 μžˆλ‹€.

Relay Store에 gcReleaseBufferSize μ˜΅μ…˜μ„ μ£Όλ©΄ release buffer의 μ‚¬μ΄μ¦ˆλ₯Ό μ‘°μ ˆν•  수 μžˆλ‹€.

const store = new Store(source, { gcReleaseBufferSize: 10 });
  • μœ„ μ½”λ“œλŠ” ReleaseBuffer의 크기λ₯Ό 10으둜 ν•˜κ² λ‹€λŠ” 뜻. 기본값이 10이기 λ•Œλ¬Έμ— μ—¬κΈ°μ„œλŠ” 사싀상 버퍼 크기λ₯Ό 바꾸지 μ•Šμ•˜μŒ.

  • 버퍼 크기λ₯Ό 0으둜 ν•˜λ©΄ release bufferλ₯Ό μ•ˆμ“°κ² λ‹€λŠ” 뜻과 κ°™μŒ. 쿼리듀은 μ¦‰μ‹œ release 되고 μž¬μ‚¬μš©λ  수 없을 것.

Staleness of Data

기본적으둜, RelayλŠ” store에 μžˆλŠ” 데이터가 λ‚‘μ•˜μ„ κ²ƒμ΄λΌλŠ” 가정을 ν•˜μ§€ μ•ŠλŠ”λ‹€. 데이터 λ¬΄νš¨ν™” APIλ₯Ό 톡해 λͺ…μ‹œμ μœΌλ‘œ λ§ˆν‚Ήν•΄μ£Όκ±°λ‚˜ 쿼리 μΊμ‹œ 만료 μ‹œκ°„λ³΄λ‹€ 였래 μ§€λ‚œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ RelayλŠ” 데이터λ₯Ό λ‚‘μ•˜λ‹€κ³  μƒκ°ν•˜μ§€ μ•Šμ„ 것이닀.

데이터가 λ‚‘μ•˜λ‹€λŠ”κ±Έ ν™•μ‹€νžˆ μ•Œ λ•ŒλŠ” λ§ˆν‚Ήμ„ ν•΄μ£ΌλŠ”κ²Œ μ’‹λ‹€. 더 μ΄μƒμ˜ mutation이 μΌμ–΄λ‚˜μ§€ μ•ŠμŒμ„ 보μž₯ν•  수 μžˆμ„ λ•Œκ°€ κ·Έλ ‡λ‹€.

RelayλŠ” μ•„λž˜μ™€ 같은 API듀을 μ œκ³΅ν•˜κ³  이걸 μ΄μš©ν•΄ store에 μžˆλŠ” 데이터가 λ‚‘μ•˜μŒμ„ ν‘œμ‹œν•  수 μžˆλ‹€.

Globally Invalidating the Relay Store

쑰금 κ³Όκ²©ν•œ 방법은 store에 μžˆλŠ” λͺ¨λ“  쿼리 μΊμ‹œλ₯Ό λ¬΄νš¨ν™”ν•˜λŠ” 것이닀. μ΄λ ‡κ²Œ μ „λΆ€λ₯Ό λ¬΄νš¨ν™”ν•˜λ©΄ RelayλŠ” ν˜„μž¬ μΊμ‹±λœ 데이터듀을 μ „λΆ€ λ‚‘μ•˜λ‹€κ³  μΈμ‹ν•˜κ²Œ λœλ‹€.

function updater(store) {
	store.invalidateStore();
}

μ΄λ ‡κ²Œ invalidateStore() λ©”μ†Œλ“œλ₯Ό 톡해 전체 store의 데이터λ₯Ό λ¬΄νš¨ν™” ν•  수 μžˆλ‹€.

  • λ¬΄νš¨ν™”λœ 데이터듀은 λ‹€μŒμ— μ ‘κ·Όν•΄ ν‰κ°€ν•˜λ € ν•  λ•Œ λ„€νŠΈμ›Œν¬λ‘œλΆ€ν„° refetch.

  • updater ν•¨μˆ˜λŠ” mutation, subscription, ν˜Ήμ€ 둜컬 storeλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” 둜직의 μΌλΆ€λ‘œ μ‚¬μš©ν•  수 있음.

Invalidating Specific Data In The Store

쑰금 더 ꡬ체적으둜, μ–΄λ–€ 데이터λ₯Ό λ¬΄νš¨ν™” ν•˜κ±°λ‚˜ ν˜Ήμ€ store에 μžˆλŠ” μ–΄λ–€ νŠΉμ •ν•œ λ ˆμ½”λ“œλ§Œ λ¬΄νš¨ν™” ν•˜λŠ” 것도 κ°€λŠ₯ν•˜λ‹€. λ°”λ‘œ μœ„μ˜ global invalidating처럼 store μ „λΆ€λ₯Ό λ¬΄νš¨ν™”ν•˜μ§€ μ•Šκ³  μ§€μ •λœ μΏΌλ¦¬λ“€λ§Œ λ¬΄νš¨ν™”λœλ‹€.

function updater(store) {
	const user = store.get('<id>');
	if(user != null) {
		user.invalidateRecord();
	}
}
  • invalidateRecord() λ©”μ†Œλ“œλ₯Ό μ‚¬μš©. invalidateStoreκ³ΌλŠ” λ‹€λ₯΄κ²Œ store의 일뢀 데이터(user)만 λ¬΄νš¨ν™”. μ΄λ ‡κ²Œ 되면 user λ ˆμ½”λ“œλŠ” λ‚‘μ•˜λ‹€κ³  λ§ˆν‚Ήλ˜μ–΄ λ‹€μŒμ— μ ‘κ·Όν•΄ ν‰κ°€ν•˜λ € ν•  λ•ŒλŠ” λ„€νŠΈμ›Œν¬λ‘œλΆ€ν„° refetch 될 것.

  • λ§ˆμ°¬κ°€μ§€λ‘œ updater ν•¨μˆ˜λŠ” mutation, subscription, ν˜Ήμ€ 둜컬 storeλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” 둜직의 μΌλΆ€λ‘œ μ‚¬μš©ν•  수 있음.

Subscribing to Data Invalidation

μœ„μ—μ„œ β€˜λ§ˆν‚Ήν•œλ‹€β€™λŠ” ν‘œν˜„μ„ μ‚¬μš©ν–ˆλŠ”λ°, λ§ˆν‚Ήμ„ ν•˜λ©΄ λ‹€μŒ 평가 μ‹œμ μ— refetch ν•˜κ³  μ΄λ ‡κ²Œ λ‹€μ‹œ 가져와진 데이터λ₯Ό μ‚¬μš©ν•œλ‹€λŠ” νŠΉμ§•μ΄ μžˆλ‹€. 예λ₯Ό λ“€μ–΄ νŽ˜μ΄μ§€ λ’€λ‘œκ°€κΈ°λ₯Ό ν•œλ‹€λ©΄ 낑은 쿼리λ₯Ό λ Œλ”λ§ν•˜λ € ν•  것이고, RelayλŠ” 낑은 쿼리λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  λ„€νŠΈμ›Œν¬λ‘œλΆ€ν„° refetchν•΄μ„œ κ°€μ Έμ˜¨ 데이터λ₯Ό μ‚¬μš©ν•  것이닀.

이런 λ§ˆν‚Ήμ€ λŒ€λΆ€λΆ„μ˜ 경우 μœ μš©ν•˜μ§€λ§Œ, 가끔은 λ¬΄νš¨ν™” μ—¬λΆ€λž‘μ€ 상관없이 μ¦‰μ‹œ refetchν•΄μ•Ό ν•  λ•Œκ°€ μžˆλ‹€.

  • λ§Œμ•½ μ§€κΈˆ μžˆλŠ” νŽ˜μ΄μ§€μ˜ 쿼리가 낑은 쿼리라면, 일뢀 λ°μ΄ν„°λŠ” μ—…λ°μ΄νŠΈκ°€ ν•„μš”. κ·Έλƒ₯ λ§ˆν‚Ήν•˜λŠ”κ²ƒ λ§ŒμœΌλ‘œλŠ” μ¦‰μ‹œ μƒˆλ‘œμš΄ 데이터λ₯Ό κ°€μ Έμ˜€μ§€λ„ μ•Šμ„κ±°κ³  낑은 데이터λ₯Ό μƒˆλ‘œμš΄ 데이터λ₯Ό 보여쀄 수 μ—†μŒ.

  • 이전 νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•˜κΈ΄ 해도 이전 νŽ˜μ΄μ§€κ°€ unmountλ˜μ§€ μ•Šμ•˜λ‹€λ©΄ 이전 νŽ˜μ΄μ§€μ˜ λ·°κ°€ λ‹€μ‹œ ν‰κ°€λ˜μ§€λ„ μ•Šμ„ 것이고, λ”°λΌμ„œ 낑은 데이터라도 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜κ²Œ 될 것이닀.

이런 상황듀이 있기 λ•Œλ¬Έμ— RelayλŠ” useSubscribeToInvalidationState λΌλŠ” 훅을 μ œκ³΅ν•œλ‹€.

function ProfilePage(props) {
  // Example of querying data for the current page for a given user
  const data = usePreloadedQuery(
    graphql`...`,
    props.preloadedQuery,
  )

  // Here we subscribe to changes in invalidation state for the given user ID.
  // Whenever the user with that ID is marked as stale, the provided callback will
  // be executed
  useSubscribeToInvalidationState([props.userID], () => {
    // Here we can do things like:
    // - re-evaluate the query by passing a new preloadedQuery to usePreloadedQuery.
    // - imperatively refetch any data
    // - render a loading spinner or gray out the page to indicate that refetch
    //   is happening.
  })

  return (...);
}
  • μ—¬κΈ°μ„œ useSubscribeInvalidationState 훅은 인자둜 id듀이 λ‹΄κΈ΄ 배열을 λ°›κ³ , μ½œλ°±λ„ ν•˜λ‚˜ λ°›λŠ”λ‹€. μ € 배열에 λ‹΄κΈ΄ idλ“€ 쀑 ν•˜λ‚˜λΌλ„ 낑은 데이터라고 λ§ˆν‚Ήλœλ‹€λ©΄ 콜백이 ν˜ΈμΆœλœλ‹€.

  • 콜백 μ•ˆμ—μ„œλŠ” refetch ν•˜κ±°λ‚˜ 낑은 데이터에 μ˜μ‘΄ν•˜λŠ” ν˜„μž¬μ˜ λ·°λ₯Ό μ—…λ°μ΄νŠΈν•  수 μžˆλ‹€. 예λ₯Ό λ“€λ©΄ top-level에 μžˆλŠ” usePreloadedQuery λ₯Ό ν˜ΈμΆœν•΄ 데이터λ₯Ό μ΅œμ‹  μƒνƒœλ‘œ μœ μ§€ν•  수 μžˆλ‹€. usePreloadedQuery λŠ” 낑은 쿼리λ₯Ό ν¬ν•¨ν•˜κ³  있기 λ•Œλ¬Έμ— λ‹Ήμ—°νžˆ refetch되고 store μΊμ‹œλ„ μ—…λ°μ΄νŠΈ 될 것이닀.

Query Cache Expiration Time

μΊμ‹±λœ 데이터λ₯Ό 가지고 μ–΄λ–€ operation을 μˆ˜ν–‰ν•˜λŠ”λ°λŠ” β€˜μΏΌλ¦¬ μΊμ‹œ 만료 μ‹œκ°„β€™λ„ 영ν–₯을 μ€€λ‹€.

  • 쿼리 μΊμ‹œ 만료 μ‹œκ°„ μ΄ν›„λ‘œ μƒˆλ‘­κ²Œ fetchλ˜μ§€ μ•Šμ€ μΏΌλ¦¬μ΄κ±°λ‚˜

  • 쿼리가 ν¬ν•¨ν•˜λŠ” λ ˆμ½”λ“œλ“€ 쀑 적어도 ν•˜λ‚˜κ°€ λ¬΄νš¨ν™”λœ λ ˆμ½”λ“œμΌ 경우

그리고 store에 μžˆλŠ” λ ˆμ½”λ“œλ“€λ‘œλ§Œ 쿼리λ₯Ό μˆ˜ν–‰ν•  수 μžˆμ„ λ•Œ 이λ₯Ό 였래된 쿼리라고 ν•œλ‹€.

쿼리가 λ‚‘μ•˜λŠ”μ§€λŠ” μƒˆλ‘œμš΄ requestκ°€ λ§Œλ“€μ–΄μ‘Œμ„ λ•Œ νŒλ‹¨ν•œλ‹€. loadQuery λ₯Ό ν˜ΈμΆœν•  λ•Œκ°€ κ·Έλ ‡μ£ . 였래된 데이터라도 이λ₯Ό μ°Έμ‘°ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈμ— μ˜ν•΄ 계속 λ Œλ”λ§λ  수 μžˆλ‹€. ν•˜μ§€λ§Œ 였래된 데이터λ₯Ό μ΄μš©ν•΄ λ§Œλ“€μ–΄μ§„ μΆ”κ°€ μš”μ²­μ€ λ„€νŠΈμ›Œν¬λ₯Ό 톡해 μƒˆλ‘œμš΄ 데이터λ₯Ό λ°›μ•„μ˜¨λ‹€.

const store = new Store(source, { queryCacheExpirationTime : 5 * 60 * 1000 });

쿼리 μΊμ‹œ λ§Œλ£Œμ‹œκ°„ μ—­μ‹œ λ§ˆμ°¬κ°€μ§€λ‘œ Storeλ₯Ό 생성할 λ•Œ μ˜΅μ…˜μœΌλ‘œ 쀄 수 μžˆλ‹€.

쿼리 μΊμ‹œ λ§Œλ£Œμ‹œκ°„ μ˜΅μ…˜μ„ λ”°λ‘œ 주지 μ•ŠμœΌλ©΄ 낑은 쿼리인지 κ²€μ‚¬ν•˜λŠ” μž‘μ—…μ€ 참쑰된 λ ˆμ½”λ“œκ°€ λ¬΄νš¨ν™”λ˜μ—ˆλŠ”μ§€ μ—¬λΆ€λ§Œ μ²΄ν¬ν•œλ‹€. λ§Œλ£Œμ‹œκ°„μ΄ λ”°λ‘œ μ§€μ •λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” λœ»μ΄λ‹€.

Last updated