데이터 패칭 라이브러리 - SWR (4. 중급 기능및 정리)

eeensu·2023년 7월 31일
0
post-thumbnail

Muatation

프론트 단계에서도 서버의 데이터를 변경해야하는 상황이 발생할 수 있다. 예를 들어 user가 개인정보를 수정, 장바구니에 담은 품목들을 삭제 등이다.

이럴 때 프론트단에서 mutate를 통해 서버의 데이터를 변경할 수 있다. 또한 필요에 따라 mutate 함수의 옵션을 사용하여 데이터 갱신 후에 서버로 요청을 보내거나, 데이터 갱신 시에 캐시를 리프레시할 수 있다.

사용법에는 useSWRConfig() 의 mutate와 useSWRMutation() 의 mutate가 있다.

기본 사용법 (1) - useSWRConfig()

버튼 클릭 시 onClick이 호출되어 user의 name을 모두 대문자로 변경하는 예제이다.

const { data, isLoading } = useSWR('/api/user/diso592', fetcher);
const { mutate } = useSWRConfig();

const onClick = () => {
  const upperName = data?.name.toLocaleUpperCase();			// 데이터에 이름이 있다면, 대문자로 변환
  const user = { ...data, name: upperName };					// 기존의 데이터와 대문자 이름을 객체로 변환

  mutate('/api/user/diso592', user);
};

mutate 함수는 SWR의 첫 번째 파라미터로 갱신하려는 데이터의 키를 받는다. 이 키는 SWR 내부 캐시에서 데이터를 식별하는데 사용된다. 두 번째 파라미터로는 새로운 데이터를 전달하거나, 데이터를 업데이트하는 콜백 함수를 전달할 수 있다.



기본 사용법 (2) - useSWRMutation()

const { mutate, isValidating } = useSWRMutation('/api/user');


차이점

useSWRConfig()mutate
SWR 라이브러리의 설정을 변경하고 전역적인 캐시를 갱신하는데 사용되는 함수로, 여러 컴포넌트에서 동일한 데이터를 사용하는 경우에 유용하다.

useSWRMutation()mutate
데이터를 변경하는 뮤테이션 작업을 처리하기 위해 사용되는 훅에 속한 함수로, 개별적인 데이터 갱신 작업에 관련하여 사용된다.




페이지 네이션

대량의 데이터를 페이지 단위로 나누어 가져오고 관리하는 방법을 제공하는 기능입니다. 페이지네이션은 사용자가 다음 페이지를 요청할 때 데이터를 미리 가져오지 않고, 필요한 시점에 페이지 단위로 서버로부터 데이터를 요청하여 효율적으로 대용량 데이터를 처리하는데 도움이 된다.

function App () {
 const [pageIndex, setPageIndex] = useState(0);

 // React state인 페이지 인덱스를 포함하는 API URL
 const { data } = useSWR(`/api/data?page=${pageIndex}`, fetcher);

 // ... 로딩 및 에러 상태를 처리

 return <div>
   {data.map(item => <div key={item.id}>{item.name}</div>)}
   <button onClick={() => setPageIndex(pageIndex - 1)}>Previous</button>
   <button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
 </div>
}



인피니트 로딩

리스트에 데이터를 이어 붙이는 "더 보기" 버튼(또는 스크롤할 때 자동으로 완료)으로 인피니트 로딩 UI를 구축하길 원하는 경우가 있다.

이를 구현하기 위해선 페이지에 동적인 수의 요청을 만들어야 한다. 하지만 react hook은 몇 가지 규칙을 갖고 있어, 다음과 같이 반복문 내에 hook을 작성할 수 없다.

  for (let i = 0; i < cnt; i++) {
    // 🚨 여기가 잘못되었습니다! 일반적으로 반복문 내에 hook을 사용할 수 없습니다.
    const { data } = useSWR(`/api/data?page=${i}`)
    list.push(data)
  }

이를 해결하기 위해 swr에서는 useSWRInfinite() hook 을 제공한다.

const { data, error, isLoading, isValidating, mutate, size, setSize } = useSWRInfinite(
	getKey, fetcher?, options?
)
  • getKey - 인덱스와 이전 페이지 데이터를 받고 페이지의 키를 반환하는 함수
  • fetcher - useSWR의 fetcher 함수와 동일
  • data - 각 페이지의 응답 값의 배열
  • mutate - useSWR의 바인딩 된 뮤테이트 함수와 동일하지만 데이터 배열을 다룸
  • size - 가져올 페이지 및 반환될 페이지의 수
  • setSize - 가져와야 하는 페이지의 수를 설정

이하 나머지 값은 기존과 동일하다.



사용 예시

const Pagenation: FC = () => {

    const { data, size, setSize } = useSWRInfinite<User[]>(getKey, fetcher);

    return (
        <div>
            {data?.map((users, i) => {
                return users.map((user) => <div key={user.id}>{user.name}</div>)
            })}
            <button onClick={() => setSize(size + 1)}>Load More</button>
        </div>
    );
};


정리

swr의 좋은 성능

  1. swr은 불필요한 요청, 리렌더링, 코드 임포트가 없음을 보장한다.

  2. swr은 기본적으로 데이터 변경을 깊게 한다. data 값이 변경되지 않았다면 리렌더링을 트리거 하지 않는다. 이는 옵션으로 커스터마이징 할 수 있다.

  3. SWR 패키지는 트리 쉐이킹이 가능(opens in a new tab)하며 부작용도 없다.

profile
안녕하세요! 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글

관련 채용 정보