zeit/swr의 pagination example에서 Scroll Position Restore를 사용해보십시오.

11665 단어 next.jsReact후크
이곳은 Next.js Advent Calendar 2019의 22일째 기사입니다.

소개



예를 들어 Youtube를 스마트폰으로 보고 있을 때, ↓와 같이 한 번 페이지 천이를 한 후 브라우저백했을 때 스크롤 위치가 맨 위로 돌아간 경험은 없을까요.



이것은 SPA가 가지고 있는 과제 중 하나로, 해결하기 위해서는 "Scroll Position Restore"라고 하는 "스크롤 위치 유지"와 그 "복원(복원)"이 필요합니다.

또, 그 이외에도 「더 읽기」등으로 화면내에 비동기로 요소가 추가되었을 경우는 그 요소도 맞추어 복원하지 않으면 올바른 스크롤 위치에는 돌아갈 수 없습니다. 이를 위해서는 복잡한 상태 관리도 필요합니다.

이처럼 "Scroll Position Restore"를 실현하기 위해서는 몇 가지 넘어야 하는 벽이 있습니다.

zeit/swr의 등장



2019년 10월, Next.js나 Now의 개발원인 Zeit로부터 "zeit/swr" 라는 라이브러리가 발표되었습니다.
그리고 이 "zeit/swr" 의 기능의 하나에 있는 「Pagination」이 「Scroll Position Restore」를 실현하기 위한 기능이 되고 있습니다!

swr(Stale-While-Revalidate) 은 주로 캐시 주위의 용어이므로 이 라이브러리도 캐시 주위의 핸들링도 포함하는 data fetch의 React Hooks 라이브러리가 되고 있습니다. 1

간단하게 해 주는 것을 쓰면, 「처음에 캐쉬 한 낡은 데이터를 보여 놓고, 그 뒤에서 최신의 데이터를 fetch 해 캐쉬와 바꿔 넣는다」라고 하는 느낌일까라고 생각합니다. 2

즉시 Pagination을 움직여보십시오.



Next.js도 그렇습니다만, 리포지토리내에 examples라고 하는 샘플집이 있어, 거기에 Pagination의 example도 있었으므로 이번은 그것을 움직여 보겠습니다.

swr/examples/pagination at master · zeit/swr

README에 쓰여진 것처럼 Setup을 끝냅니다 (이 샘플 자체도 Next.js가 사용되었습니다).
$ curl https://codeload.github.com/zeit/swr/tar.gz/master | tar -xz --strip=2 swr-master/examples/pagination
$ cd pagination
$ yarn
$ yarn dev

시작된 서버에 액세스하면 다음 페이지가 나타납니다. 「load more」로 읽어들인 요소가, 페이지 천이를 해 브라우저 백을 해도 표시되고 있는 것을 알 수 있다고 생각합니다! 또, 스크롤 위치도 유지되고 있을 것 같네요. 3



구현은 이런 느낌입니다.
import fetch from '../libs/fetch'
import Link from 'next/link'

import useSWR, { useSWRPages } from 'swr'

export default () => {
  const {
    pages,
    isLoadingMore,
    isReachingEnd,
    loadMore
  } = useSWRPages(
    // page key
    'demo-page',

    // page component
    ({ offset, withSWR }) => {
      const { data: projects } = withSWR(
        // use the wrapper to wrap the *pagination API SWR*
        useSWR('/api/projects?offset=' + (offset || 0), fetch)
      )
      // you can still use other SWRs outside

      if (!projects) {
        return <p>loading</p>
      }

      return projects.map(project => 
        <p key={project.id}>{project.name}</p>
      )
    },

    // one page's SWR => offset of next page
    ({ data: projects }) => {
      return projects && projects.length
        ? projects[projects.length - 1].id + 1
        : null
    },

    // deps of the page component
    []
  )

  return <div>
    <h1>Pagination (offset from data)</h1>
    {pages}
    <button onClick={loadMore} disabled={isReachingEnd || isLoadingMore}>
      {isLoadingMore ? '. . .' : isReachingEnd ? 'no more data' : 'load more'}
    </button>
    <hr />
    <Link href="/page-index"><a>page index based pagination </a></Link><br/>
    <Link href="/about"><a>go to another page </a></Link>
  </div>
}
useSWRPages() 의 인수로서, 캐시 키로서도 사용되는 페이지명, 실제로 fetch한 데이터를 사용해 생성하는 Component, 다음 페이지의 offset등을 설정하고 있습니다.

여기의 설명은 코드 측에 시퀀스 다이어그램이있었습니다. 그래서 그쪽을 보면 보다 알기 쉬울까 생각합니다.

조금 만져 보거나 issue 등도 보았는데, 아직 스크롤 위치의 복원이 약간 불완전하거나 캐시의 스토어를 만지려고 했을 때에 불편함은 있지만 단순한 어플리케이션이면 비교적 간단 에 사용할 수 있을 것 같은 느낌이었습니다.

사이고에게



zeit/swr은 아직 발표된 지 얼마 안되어 이용 실적도 많지 않지만, 빈번하게 개발되고 있어 무엇보다 개발원이 zeit이기 때문에 향후 점점 Next.js와 잘 협조해 진화해 나갈 것입니다. Next를 사용하시는 분은 꼭 그 동향에 주목해 보세요!

이상, 22일째의 기사였습니다!



이 도서관 계기로 swr 자체를 다시 공부했습니다. . 이 기사 가 알기 쉬웠습니다.

자세한 것은 이 기사 이나 이 기사 를 추천합니다!

알기 쉽게 하기 위해 한 번에 읽는 데이터 수를 3건에서 10건으로 변경하고 있습니다.

좋은 웹페이지 즐겨찾기