React Suspense에서 불필요한 드로잉 처리 제거

16546 단어 Reacttech
React FreezeSuspense의 독특한 사용법을 제시해 기사로 정리했다.
https://github.com/software-mansion-labs/react-freeze

안녕: 이른바 React Suspense


리액트 수spense는 리액트 16.6에서 실험적으로 추가된 구성요소여서 로드 상태임을 선언적으로 지정할 수 있다.
https://ja.reactjs.org/docs/concurrent-mode-suspense.html
문서에 Suspense는 React에 데이터 읽기가 준비되었는지 전달하는 메커니즘으로 주로 데이터를 얻는 데 사용된다고 쓰여 있다.
const ProfilePage = React.lazy(() => import('./ProfilePage')); // Lazy-loaded

// Show a spinner while the profile is loading
<Suspense fallback={<Spinner />}>
  <ProfilePage />
</Suspense>
데이터가 호출 중인지 여부는Suspense의 서브어셈블리에서throw proomise를 통해 React에 전달됩니다.
function ProfileDetails() {
  const user = resource.user.read();  // throw promise here
  return <h1>{user.name}</h1>;
}
이 규격 자체가 재미있고 보도가 될 수도 있다.(이곳에서 사랑을 끊는다.)
https://overreacted.io/ja/algebraic-effects-for-the-rest-of-us/
https://qiita.com/uhyo/items/255760315ca61544fe33

React Freeze


React Freeze는 이런 Suspense를 이용한 프로그램 라이브러리다.
원래 React 측에서 데이터를 가져올 때 사용하는 것이 주요한 용례라고 말했는데, 이 프로그램 라이브러리의 목적은 어느 순간에 사용자가 표시하지 않은 응용 부분의 불필요한 리셋을 피하기 위해서이다.
어떻게 이루어졌을까요?
사실 프로그램 라이브러리의 설치도 매우 간단하고 재미있다.
// ref: https://github.com/software-mansion-labs/react-freeze/blob/main/src/index.tsx
function Suspender({
  freeze,
  children,
}: {
  freeze: boolean;
  children: React.ReactNode;
}) {
  const promiseCache = useRef<StorageRef>({}).current;
  if (freeze && !promiseCache.promise) {
    promiseCache.promise = new Promise((resolve) => {
      promiseCache.resolve = resolve;
    });
    throw promiseCache.promise;
  } else if (freeze) {
    throw promiseCache.promise;
  } else if (promiseCache.promise) {
    promiseCache.resolve!();
    promiseCache.promise = undefined;
  }

  return <Fragment>{children}</Fragment>;
}

export function Freeze({ freeze, children, placeholder = null }: Props) {
  return (
    <Suspense fallback={placeholder}>
      <Suspender freeze={freeze}>{children}</Suspender>
    </Suspense>
  );
}
주목한 것은 Suspender 구성 요소에서promise Cache의 실현 부분이다. freezeprops가 진짜인 동안(freeze에서) 빈 promise를 계속 갱신하는 것이다.그리고 Suspender는 프로미스트를 계속하는 동안 Freeze 구성 요소 내의 Suspense에 따라 그 구조를 감시합니다.
이 실시의 흥미로운 점은freeze에서Suspense는 하위 구성 요소를 더 이상 그릴 수 없고,대신suspense의fallback을 그릴 수 있으며, 필요하지 않은 그리기 처리를 건너뛰었다는 것이다.
또한, Suspense가 대체하는 서브어셈블리는 언로드하지 않는 성질이 있으므로 상태(여기서 말하는 상태는 state가 아니라 스크롤하는 위치, input, 로드된 이미지 등)를 유지한 상태에서 재그리기를 억제할 수 있습니다.
이 프로그램 라이브러리의 주요 구상 용례는 응용 프로그램의 겹침형 내비게이션이다. 이Suspense의 성격을 이용하여 Stack 맨 위에 있는 구성 요소 이외의 구성 요소freeze를 사용하면 화면의 상태를 효율적으로 잠글 수 있다.

고찰하다.


React Freeze의 언로드 없이 화면을 다운시키는 기능을 통해 Native/웹 화면 최적화 방법 중 하나인 Suspense를 활용할 수 있습니다.설치 자체가 간단하기 때문에 많은 것을 응용할 수 있을 것 같다.
겹쳐쓰기 보기는 주요한 용례로 구상되었지만 웹에서의 이용에 대해서도 약간 언급되었다. 예를 들어 모드 등 화면을 덮어쓰는 구성 요소에 사용될 수 있다.
function App() {
  const [showModal, setShowModal] = useState(false)
  return (
    <Fragment>
      <Freeze freeze={showModal}>
        <AppPage onOpenModal={() => setShowModal(true)} />
      </Freeze>
      <Freeze freeze={!showModal}>
        <AppModal open={showModal} />
      </Freeze>
    </Fragment>
  );
}
또한 React Freeze는 Suspense가 데이터를 가져올 때의 상태 이외의 용도에서도 사용할 수 있음을 암시한다고 할 수 있다.
최초의 Suspense를 제공하는 목적은 React에 데이터를 전달할 수 있는 읽기가 준비되었는지 여부라고 생각합니다. 그러나 이것뿐만 아니라 구성 요소가 그릴 수 있는 상태에 있는 메커니즘을 전달하고 더욱 일반화된 이해를 할 수 있다고 생각합니다.
글쎄, 리액트 수퍼스가 더 가능성이 크겠네.

좋은 웹페이지 즐겨찾기