본문 바로가기

useTransition 본문

React

useTransition

개발자로 거듭나기 2023. 10. 3. 15:55
반응형

useTransition

개념 및 사용법

  • useTransition은 UI를 차단하지 않고 state를 업데이트할 수 있는 React 훅입니다.
  • useTransition은 정확히 두 개의 항목이 있는 배열을 반환합니다:
    1. 보류 중인 트랜지션이 있는지 여부를 알려주는 isPending 플래그
    2. state 업데이트를 트랜지션으로 표시할 수 있는 [startTransition 함수]  (아무것도 return 하지 않음)
  • 사용법
function TabContainer() {
  const [isPending, startTransition] = useTransition();
  const [tab, setTab] = useState('about');

  function selectTab(nextTab) {
    startTransition(() => {
      setTab(nextTab);
    });
  }
  // ...
}

 

주의사항

  • 해당 state의 set 함수에 접근할 수 있는 경우에만 업데이트를 트랜지션으로 감쌀 수 있습니다. 일부 prop이나 커스텀 훅 값에 대한 응답으로 트랜지션을 시작하려면, 대신 [useDeferredValue]를 사용해보세요.
  • startTransition에 전달하는 함수는 동기식이어야 합니다. React는 이 함수를 즉시 실행하여, 실행하는 동안 발생하는 모든 state 업데이트를 트랜지션으로 표시합니다. 나중에 더 많은 state 업데이트를 수행하려고 하면(예: 타임아웃), 트랜지션으로 표시되지 않습니다.
  • 트랜지션으로 표시된 state 업데이트는 다른 state 업데이트에 의해 중단됩니다. 예를 들어, 트랜지션 내에서 차트 컴포넌트를 업데이트한 다음, 차트가 다시 렌더링되는 도중에 입력을 시작하면 React는 입력 업데이트를 처리한 후 차트 컴포넌트에서 렌더링 작업을 다시 시작합니다.
  • input을 제어하는 state 변수에는 트랜지션을 사용할 수 없습니다.

 

사용법

  • TabButton의 onClick함수를 startTransition으로 감싸서 사용자 상호작용을 차단하지 않습니다.
  • post탭을 클릭하고 바로 contact탭을 클릭해보세요 앱이 중단되지 않습니다.
  • startTransition을 제거하고 한번 테스트 해보세요, posts탭이 눌렸다고 사용자는 알 수 없습니다.
  • isPending 변수는 transition이 진행중인가를 알려줍니다.
  • useTransition.tsx
import AboutTab from "@/components/AboutTab";
import ContactTab from "@/components/Contact";
import PostsTab from "@/components/Posts";
import TabButton from "@/components/TabButton";
import { useState } from "react";
export default function TabContainer() {
  const [tab, setTab] = useState("about");
  return (
    <>
      <TabButton isActive={tab === "about"} onClick={() => setTab("about")}>
        About
      </TabButton>
      <TabButton isActive={tab === "posts"} onClick={() => setTab("posts")}>
        Posts (slow)
      </TabButton>
      <TabButton isActive={tab === "contact"} onClick={() => setTab("contact")}>
        Contact
      </TabButton>
      <hr />
      {tab === "about" && <AboutTab />}
      {tab === "posts" && <PostsTab />}
      {tab === "contact" && <ContactTab />}
    </>
  );
}
  • TabButton.tsx
import { useTransition } from "react";

type TabButtonProps = {
  children: React.ReactNode;
  isActive: boolean;
  onClick: () => void;
};

export default function TabButton({
  children,
  isActive,
  onClick,
}: TabButtonProps) {
  const [isPending, startTransition] = useTransition();

  if (isActive) {
    return <b>{children}</b>;
  }

  if (isPending) {
    return <b className="pending">{children}</b>;
  }

  return (
    <button
      onClick={() => {
        startTransition(() => {
          onClick();
        });
      }}
    >
      {children}
    </button>
  );
}
  • AboutTab.tsx
export default function AboutTab() {
  return <p>Welcome to my profile!</p>;
}
  • Posts.tsx
import { memo } from "react";

const PostsTab = memo(function PostsTab() {
  // 한 번만 기록합니다. 실제 속도저하는 SlowPost 내부에서 이뤄집니다.
  let items = [];
  for (let i = 0; i < 500; i++) {
    items.push(<SlowPost key={i} index={i} />);
  }
  return <ul className="items">{items}</ul>;
});

function SlowPost({ index }: { index: number }) {
  let startTime = performance.now();
  while (performance.now() - startTime < 1) {
    // 매우 느린 코드를 구현하기 위해 항목마다 1ms동안 아무것도 하지 않도록 합니다
  }

  return <li className="item">Post #{index + 1}</li>;
}

export default PostsTab;
  • Contact.tsx
export default function ContactTab() {
  return (
    <>
      <p>You can find me online here:</p>
      <ul>
        <li>admin@mysite.com</li>
        <li>+123456789</li>
      </ul>
    </>
  );
}

 

출처

https://react-ko.dev/reference/react/useTransition

반응형

'React' 카테고리의 다른 글

React 배너 슬라이더 만들기 + touch evnet  (3) 2024.01.04
useDefferedValue  (1) 2023.10.03
RTK Query 캐쉬 무효화  (0) 2023.10.03
Comments