cosnt { data, error, isValidating, mutate } = useSWR(key, fetcher, options);
null을 사용하거나 함수를 key로 전달하여 데이터를 조건부로 가져옵니다. 함수가 falsy값을 던지거나 반환하면 SWR은 요청을 시작하지 않는다.
flasy가 뭐지? 링크
// 조건부 가져오기
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)
// ...또는 falsy 값 반환
const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher)
// ...또는 user.id가 정의되지 않았을 때 에러 throw
const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher)
SWR은 다른 데이터에 의존하는 데이터를 가져오는 것 또한 허용합니다. 이는 다음 데이터를 가져오기 위한 동적 데이터 조각이 필요할 때, 직렬 가져오기 뿐만 아니라 기능한 최대 병렬 처리를 보장합니다.
function MyProjects () {
const { data: user } = useSWR('/api/user')
const { data: projects } = useSWR(() => '/api/projects?uid=' + user.id)
// 함수를 전달할 때, SWR은 반환 값을 `key`로 사용한다.
// 함수가 falsy를 던지거나 반환한다면,
// SWR은 일부 의존성이 준비되지 않은 것을 알게 된다.
// 이 예시의 경우 `user.id`는 `user`가 로드되지 않았을 때
// 에러를 던진다.
if (!projects) return 'loading...'
return 'You have ' + projects.length + ' projects'
}
const { data, error } = useSWR(key, fetcher)
이것은 SWR의 아주 핵심적인 API다. 여기의 fetcher는 SWR의 key를 받고 데이터를 반환하는 비동기 함수다.
반환된 값은 data로 전달되며, 만약 throws라면 error로 잡힌다.
데이터 가져오기를 다루는 어떠한 라이브러리든 사용할 수 있다. axios와 GraphQL을 예로 들어보겠다.
import axios from "axios"
const fetcher = url => axios.get(url).then(res => res.data)
function App(){
const { data, error } = useSWR('/api/data', fetcher)
// ...
}
import { request } from 'graphql-request'
const fetcher = query => request('/api/graphql', query)
function App () {
const { data, error } = useSWR(
`{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}`,
fetcher
)
// ...
}
fetcher가 이행한 주어진 키에 대한 데이터(로드되지 않았다면 undefined)
fetcher가 던진 에러(또는 undefined)
요청이나 갱신 로딩의 여부
캐시 된 데이터를 뮤테이트하기 위한 함수
mutate(key, data, options)
이 예시는 유저가 '로그아웃'버튼을 클릭할 때 로그인 정보( 내부)를 자동으로 갱신하는 방법을 보여줍니다.
import useSWR, { useSWRConfig } from 'swr'
function App () {
const { mutate } = useSWRConfig()
return (
<div>
<Profile />
<button onClick={() => {
// 쿠키를 만료된 것으로 설정
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
// 이 키로 모든 SWR에게 갱신하도록 요청
mutate('/api/user')
}}>
Logout
</button>
</div>
)
}
동일한 캐시 공급자 범위 아래의 SWR hook에게 브로드캐스팅합니다. 캐시 공급자가 존재하지 않을 경우, 모든 SWR hook으로 브로드캐스팅한다.
많은 경우에, 데이터에 로컬 뮤테이션을 적용하는 것은 변경을 더 빠르게 느낄 수 있게 해주는 좋은 방법입니다. 데이터의 원격 소스를 기다릴 필요가 없다.
mutate를 사용하면 데이터를 재검증하고 최종적으로 최신 데이터로 대체하는 동안에, 로컬 데이터를 프로그래밍 방식으로 업데이트할 수 있다.
import useSWR, { useSWRConfig } from 'swr'
function Profile () {
const { mutate } = useSWRConfig()
const { data } = useSWR('/api/user', fetcher)
return (
<div>
<h1>My name is {data.name}.</h1>
<button onClick={async () => {
const newName = data.name.toUpperCase()
const user = { ...data, name: newName }
const options = { optimisticData: user, rollbackOnError: true }
// 로컬 데이터를 즉시 업데이트하고
// 데이터 업데이트 요청을 전송하고
// 로컬 데이터가 올바른지 확인하기 위해 갱신(다시 가져오기)을 트리거한다.
mutate('/api/user', updateFn(user), options);
}}>Uppercase my name!</button>
</div>
)
}
*updateFn은 원격 뮤테이션을 다루기 위한 promise 또는 비동기 함수여야 한다. 업데이트한 데이터를 반환해야 한다.*
현재 데이터를 기반으로 데이터의 일부를 업데이트하려는 경우가 있다.
mutate를 사용해 현재 킷 된 값을 받는(있으면 업데이트된 문서를 반환) 비동기 함수를 전달할 수 있다.
mutate('/api/todos', async todos => {
// ID `1`을 갖는 todo를 업데이트해 완료되도록 해보자
// 이 API는 업데이트된 데이터를 반환한다
const updatedTodo = await fetch('/api/todos/1', {
method: 'PATCH',
body: JSON.stringify({ completed: true })
})
// 리스트를 필터링하고 업데이트된 항목을 반환한다
const filteredTodos = todos.filter(todo => todo.id !== '1')
return [...filteredTodos, updatedTodo]
// Since the API already gives us the updated information,
// we don't need to revalidate here.
}, { revalidate: false })
또한 populateCache 옵션도 사용할 수 있다.
const updateTodo = () => fetch('/api/todos/1', {
method: 'PATCH',
body: JSON.stringify({ completed: true })
})
mutate('/api/todos', updateTodo, {
populateCache: (updatedTodo, todos) => {
// list를 필터링하고 업데이트된 값을 반환
const filteredTodos = todos.filter(todo => todo.id !== '1')
return [...filteredTodos, updatedTodo]
},
// API가 이미 업데이트된 정보를 준 이후로,
// 우리는 재확인 할 필요없음
revalidate: false
})
여러분 대부분은 아마도 캐시를 업데이트하기 위한 어떤 데이터가 필요할 것입니다. 데이터는 mutate로 전달했던 프로미스나 비동기 함수로부터 이행되었거나 반환되었습니다.
mutate로 전달된 함수는 적합한 캐시 값을 업데이트하기 위해 사용되는 업데이트된 문서를 반환합니다. 해당 함수를 실행하는 동안 에러가 발생한다면, 적절하게 처리할 수 있도록 에러가 던져집니다.
try {
const user = await mutate('/api/user', updateUser(newUser))
} catch (error) {
// 여기에서 user를 업데이트하는 동안 발생하는 에러를 처리
}
useSWR에 의해 반환된 SWR 객체는 SWR의 키로 미리 바인딩 된 mutate() 함수도 포함합니다. 기능적으로는 전역 mutate 함수와 동일하지만 key 파라미터를 요구하지 않습니다.
import useSWR from 'swr'
function Profile () {
const { data, mutate } = useSWR('/api/user', fetcher)
return (
<div>
<h1>My name is {data.name}.</h1>
<button onClick={async () => {
const newName = data.name.toUpperCase()
// 데이터를 업데이트하기 위해 API로 요청을 전송
await requestUpdateUsername(newName)
// 로컬 데이터를 즉시 업데이트하고 갱신(refetch)
// 노트: 미리 바인딩 되었으므로 useSWR의 뮤테이트를 사용할 때는 key가 요구되지 않음
mutate({ ...data, name: newName })
}}>Uppercase my name!</button>
</div>
)
}
추가적인 옵션은 정말 많다. 직접 공식사이트에서 찾아보는 것을 추천한다. 여기서는 간단하게 몇 개만 알아보자.
fallbackData : 반환된 초기 데이터(hook 별로 존재)
onSuccess(data, key, config): 요청이 성공적으로 종료되었을 경우의 콜백 함수
참고 : SWR 공식사이트
공식문서 복붙....