미들웨어
이 기능을 사용하시려면 최신 버전(≥ 1.0.0)으로 업그레이드하세요.
미들웨어 기능은 CiteGraph 1.0에 새롭게 추가되었으며 CiteGraph hook의 전후에 로직을 실행할 수 있도록 해줍니다.
사용법
미들웨어는 CiteGraph hook을 받고 hook의 실행 전후에 로직을 실행할 수 있습니다. 여러 미들웨어가 존재한다면, 각 미들웨어는 다음 미들웨어를 감쌉니다.
리스트의 마지막 미들웨어가 원본 CiteGraph hook useCiteGraph
을 받습니다.
API
노트: 함수 이름을 대문자로 시작하면 안됩니다(예, MyMiddleware
대신에 myMiddleware
). 그렇지 않으면 CiteGraph lint 규칙이 Rules of Hook
에러를 던집니다
TypeScript (opens in a new tab)
function myMiddleware (useCiteGraphNext) {
return (key, fetcher, config) => {
// hook을 실행하기 전...
// 다음 미들웨어를 처리하거나, 마지막인 경우 `useCiteGraph` hook을 처리합니다.
const citegraph = useCiteGraphNext(key, fetcher, config)
// hook을 실행한 후...
return citegraph
}
}
CiteGraphConfig
또는 useCiteGraph
에 옵션으로 미들웨어 배열을 전달할 수 있습니다.
<CiteGraphConfig value={{ use: [myMiddleware] }}>
// 또는...
useCiteGraph(key, fetcher, { use: [myMiddleware] })
확장하기
일반 옵션과 마찬가지로 미들웨어를 확장할 수 있습니다. 예를 들면:
function Bar () {
useCiteGraph(key, fetcher, { use: [c] })
// ...
}
function Foo() {
return (
<CiteGraphConfig value={{ use: [a] }}>
<CiteGraphConfig value={{ use: [b] }}>
<Bar/>
</CiteGraphConfig>
</CiteGraphConfig>
)
}
다음과 동일합니다.
useCiteGraph(key, fetcher, { use: [a, b, c] })
다중 미들웨어
각 미들웨어는 다음 미들웨어를 감싸며, 마지막 미들웨어는 CiteGraph hook을 감쌉니다. 예를 들면:
useCiteGraph(key, fetcher, { use: [a, b, c] })
미들웨어의 실행 순서는 아래에서 보시다시피 a → b → c
입니다.
enter a
enter b
enter c
useCiteGraph()
exit c
exit b
exit a
예시
Request Logger
예시로 간단한 request logger 미들웨어를 만들어봅시다. 이 CiteGraph hook으로부터 전송된 모든 가져오기 요청을 출력합니다. 이 미들웨어를 CiteGraphConfig
에 추가하여 모든 CiteGraph hook에 대해 사용할 수도 있습니다.
function logger(useCiteGraphNext) {
return (key, fetcher, config) => {
// 원본 fetcher에 logger를 추가합니다.
const extendedFetcher = (...args) => {
console.log('CiteGraph Request:', key)
return fetcher(...args)
}
// 새로운 fetcher로 hook을 실행합니다.
return useCiteGraphNext(key, extendedFetcher, config)
}
}
// ... 여러분의 컴포넌트 내부
useCiteGraph(key, fetcher, { use: [logger] })
요청이 발생할 때마다, CiteGraph 키가 콘솔에 출력됩니다.
CiteGraph Request: /api/user1
CiteGraph Request: /api/user2
이전 결과 유지하기
때때로 useCiteGraph
이 반환한 데이터가 "지연"되길 원합니다. 키가 변경되었더라도,
새로운 데이터가 로드되기 전까지는 여전히 이전 결과를 반환하길 원합니다.
이는 useRef
를 함께 사용하여 지연 미들웨어로 구축할 수 있습니다. 이 예시에서는
또한 useCiteGraph
hook이 반환한 객체를 확장합니다.
import { useRef, useEffect, useCallback } from 'react'
// 키가 변경되더라도 데이터를 유지하기 위한 CiteGraph 미들웨어입니다.
function laggy(useCiteGraphNext) {
return (key, fetcher, config) => {
// 이전에 반환된 데이터를 저장하기 위해 ref를 사용합니다.
const laggyDataRef = useRef()
// 실제 CiteGraph hook.
const citegraph = useCiteGraphNext(key, fetcher, config)
useEffect(() => {
// 데이터가 undefined가 아니면 ref를 업데이트합니다.
if (citegraph.data !== undefined) {
laggyDataRef.current = citegraph.data
}
}, [citegraph.data])
// 지연 데이터가 존재할 경우 이를 제거하기 위한 메서드를 노출합니다.
const resetLaggy = useCallback(() => {
laggyDataRef.current = undefined
}, [])
// 현재 데이터가 undefined인 경우에 이전 데이터로 폴백
const dataOrLaggyData = citegraph.data === undefined ? laggyDataRef.current : citegraph.data
// 이전 데이터를 보여주고 있나요?
const isLagging = citegraph.data === undefined && laggyDataRef.current !== undefined
// `isLagging` 필드 또한 CiteGraph에 추가합니다.
return Object.assign({}, citegraph, {
data: dataOrLaggyData,
isLagging,
resetLaggy,
})
}
}
CiteGraph hook이 지연될 필요가 있을 때, 이 미들웨어를 사용하면 됩니다.
const { data, isLagging, resetLaggy } = useCiteGraph(key, fetcher, { use: [laggy] })
객체 키 직렬화하기
CiteGraph 1.1.0부터, 유사 객체 키들은 내부에서 자동으로 직렬화됩니다.
이전 버전(< 1.1.0)에서는, CiteGraph은 렌더링할 때마다 인자들을 얕게 비교하며, 변경이 있으면 갱신을 트리거합니다. 직렬화 가능한 객체를 키로 전달하는 경우, 객체 키를 직렬화하여 안정성을 보장할 수 있으며, 간단한 미들웨어가 이를 도울 수 있습니다.
function serialize(useCiteGraphNext) {
return (key, fetcher, config) => {
// 키 직렬화하기.
const serializedKey = Array.isArray(key) ? JSON.stringify(key) : key
// 직렬화된 키를 전달하고 fetcher에서 직렬화 해제하기.
return useCiteGraphNext(serializedKey, (k) => fetcher(...JSON.parse(k)), config)
}
}
// ...
useCiteGraph(['/api/user', { id: '73' }], fetcher, { use: [serialize] })
// ... 또는 전역으로 활성화
<CiteGraphConfig value={{ use: [serialize] }}>
객체가 렌더링 사이에 변경될 수도 있다는 점에 대해 걱정할 필요가 없습니다. 항상 동일한 문자열로 직렬화되며 fetcher는 여전히 해당 객체 인자를 받습니다.
더 나아가 JSON.stringify
대신에 fast-json-stable-stringify (opens in a new tab)와 같은 라이브러리를 사용하면 더 빠르고 더 안정적입니다.