Bound mutate는 현재 키를 기반으로 데이터로 변경하는 빠른 방법입니다. useSWR 함수에 전달된 키와 연결된 키는 캐시에서 데이터를 찾을 때 사용되며, 이렇게 찾은 데이터는 첫 번째 인자로 반환됩니다.
이전 섹션의 global 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)를 합니다. // NOTE: key는 미리 바인딩되어 있으므로 useSWR의 mutate를 사용할 때 필요하지 않습니다. mutate({ ...data, name: newName }) }}>Uppercase my name!</button> </div> )}
데이터 없이 mutate(key) (또는 바인딩된 mutate API로 mutate())를 호출하면, 리소스에 대한 재검증(데이터를 만료된 것으로 표시하고 refetch를 트리거) 합니다.
이 예제는 사용자가 "로그아웃" 버튼을 클릭할 때 로그인 정보(예: <Profile /> 내부)를 자동으로 다시 가져오는 방법을 보여줍니다.
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=/;' // `/api/user` 라는 키를 가진 모든 SWR에게 재검증을 지시합니다. mutate('/api/user') }}> Logout </button> </div> )}
동일한 cache provider 범위 내의 SWR hook에 전달합니다. cache provider가 존재하지 않으면 모든 SWR hook에 전달합니다.
useSWRMutation은 useSWR과 캐시 저장소를 공유하므로 useSWR 간의 경합 조건을 감지하고 피할 수 있습니다.
또한 optimistic update 및 오류 발생 시 롤백과 같은 mutate의 기능도 지원합니다. 이러한 옵션은 useSWRMutation과 트리거 함수를 통해 전달할 수 있습니다.
optimisticData가 설정되어 있는 경우, optimistic data가 사용자에게 표시되지만 remote mutation이 실패할 수 있습니다.
이 경우, rollbackOnError를 활용하여 로컬 캐시를 이전 상태로 되돌리면 사용자에게 올바른 데이터가 표시되는지 확인할 수 있습니다.
remote mutation 요청이 업데이트 된 데이터를 직접 반환하는 경우도 있으므로 데이터를 로드하기 위해 추가 가져오기(extra refetch)를 수행할 필요가 없습니다.
populateCache 옵션을 활성화하여 mutation 응답으로 useSWR에 대한 캐시를 업데이트 할 수 있습니다.
const updateTodo = () => fetch('/api/todos/1', { method: 'PATCH', body: JSON.stringify({ completed: true })})mutate('/api/todos', updateTodo, { populateCache: (updatedTodo, todos) => { // 목록을 필터링 하고 업데이트 된 항목과 함께 반환됩니다. const filteredTodos = todos.filter(todo => todo.id !== '1') return [...filteredTodos, updatedTodo] }, // API가 이미 업데이트 된 정보를 제공하므로, // 여기서 다시 유효성을 검사 할 필요가 없습니다. revalidate: false})
또는 useSWRMutation hook을 사용합니다.
useSWRMutation('/api/todos', updateTodo, { populateCache: (updatedTodo, todos) => { // 목록을 필터링 하고 업데이트 된 항목과 함께 반환됩니다. const filteredTodos = todos.filter(todo => todo.id !== '1') return [...filteredTodos, updatedTodo] }, // API가 이미 업데이트 된 정보를 제공하므로, // 여기서 다시 유효성을 검사 할 필요가 없습니다. revalidate: false})
optimisticData 및 rollbackOnError를 함께 사용하면 완벽한 optimistic UI를 경험할 수 있습니다.
일반적인 useSWR hook은 포커스, 폴링 또는 기타 조건으로 인해 언제든지 데이터를 새로고침 할 수 있습니다.
이렇게 하면 표시되는 사용자 아이디를 최대한 최신으로 유지할 수 있습니다.
그러나, useSWR을 다시 가져오는 것과 거의 동시에 발생할 수 있는 mutation이 있기 때문에 getUser 요청이 더 일찍 시작되지만 updateUser 보다 오래 걸리는 경합 조건(Race Conditions)이 있을 수 있습니다.
다행히도, useSWRMutation은 이 작업을 자동으로 처리합니다.
mutation 후에는 useSWR에 진행 중인 요청을 버리고 재검증 하도록 지시하여 오래된 데이터가 표시되지 않도록 합니다.
mutate를 사용하면 현재 캐시된 값(있는 경우)을 전달받는 비동기 함수를 전달할 수 있으며, 이 함수는 업데이트된 문서를 반환합니다.
mutate('/api/todos', async todos => { // ID `1`의 할 일을 업데이트 하여 완료해 봅시다. // 이 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] // API가 이미 업데이트 된 정보를 제공하므로, // 여기서 다시 유효성을 검사 할 필요가 없습니다.}, { revalidate: false })
global mutate API는 key를 인자로 받아 재검증 할 키를 반환하는 필터 함수를 허용합니다. 필터 함수는 기존 모든 캐시 키에 적용됩니다.
import { mutate } from 'swr'// 또는 cache provider 를 사용자 정의한 경우, hook에서 사용할 수 있습니다.// { mutate } = useSWRConfig()mutate( key => typeof key === 'string' && key.startsWith('/api/item?id='), undefined, { revalidate: true })
배열과 같은 모든 키 유형에서도 작동합니다. mutation은 첫 번째 요소가 'item'인 모든 키와 일치합니다.