데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      새롭게 발표된 React 19 버전은 무엇이 달라졌나?

      say 24.06.12
      11,118 10 1
      DEVOTEE 요약
      React 19 버전의 주요 변경점은 다음과 같습니다: 1. `useFormState` 훅이 `useActionState`로 대체되어, action 호출 시 최신 결과 데이터와 `pending` 상태를 반환합니다. 2. ReactDOM에서 비동기 함수를 지원하는 `useFormStatus` 훅이 새로 추가되어, 하위 컴포넌트에서 상위 `form`의 상태를 쉽게 접근할 수 있습니다. 3. `useOptimistic` 훅은 요청 중 화면을 빠르게 업데이트하여 사용자의 경험을 개선시킵니다.

      새롭게 발표된 React 19 버전은 무엇이 달라졌나?

      반갑습니다🙌🏻 데보션 커뮤니티 여러분 !

      데보션영 3기 5CEAN 팀의 정세희입니다 😊


      얼마전 2024년 4월, 리액트 공식문서에서 React 19 베타버전을 발표했는데요.


      2022년 3월에 18버전을 발표한 이후로 이렇다할 버전 발표가 없었어서

      “전세계적으로 인기있는 기술인 React가 이렇게나 느린 업데이트를 한다고 ?“ 하면서 불평불만도 많았다고 합니다.


      불과 일주일전에 확인할 때만 해도 React 19 Beta 버전이었는데, 지금 데보션에 올릴 글을 적으면서 보니

      최근에 React 19 RC 버전으로 바뀐 걸 보면 정말 최종의 찐 최종까지 오지 않았나 - 싶습니다.

      (아주 안정된 v19.0이 얼마 남지 않을 것 같네요 !)


      달라진점 #1 : useActionState 훅

      https://github.com/facebook/react/pull/28491

      • useFormState 훅 → useActionState 훅

        • 기존 ReactDOM의 useFormState 훅이 주는 혼란과 제약사항을 수정하고 더욱 개선시켜 새롭게 발표된 훅 ‘useActionState’입니다.

        • 기존의 useFormState 훅은 폐기하였습니다.

      • 반환되는 튜플에 ‘pending’ 상태를 추가

        • useFormStatus가 pending 상태값을 주는 것과는 달리, useFormState는 해당 값을 주지 않아서 혼란을 야기합니다.

        • 따라서 새로운 useActionState에서는 Action이 호출되면 가장 최근 결과의 data와 pending 상태를 반환합니다.

      • ‘react’ 패키지로 훅 이동

        • 태그에만 쓰였던 useFormState가 ReactDOM 패키지에만 해당되었던 것과는 달리, 태그 이외의 모든 렌더러에서 사용할 수 있도록 ‘react’ 패키지로 훅을 이동했습니다.

      #1-1 레퍼런스

      • Type

        function useActionState<State>(
                action: (state: Awaited<State>) => State | Promise<State>,
                initialState: Awaited<State>,
                permalink?: string,
            ): [state: Awaited<State>, dispatch: () => void, boolean];
        • parameter ⇒ action, initialState, permalink 를 변수로 가집니다

          • action

          • initialState

          • permalink

        • return ⇒ (state, dispatch, pending)을 가진 tuple 형태로 반환합니다.

          • state : 반환된 action의 마지막 상태

          • dispatch : 래핑된 action을 전달하기 위한 메서드

          • pending : action과 업데이트가 수행된 모든 상태의 대기(pending) 상태

      #1-2 사용

      기존의 useFormState와 비슷하게 사용할 수 있습니다.

      import { useActionState } from "react"; // not react-dom
      
      function Form({ formAction }) {
        const [state, action, isPending] = useActionState(formAction);
      
        return (
          <form action={action}>
            <input type="email" name="email" disabled={isPending} />
            <button type="submit" disabled={isPending}>
              Submit
            </button>
            {state.errorMessage && <p>{state.errorMessage}</p>}
          </form>
        );
      }

      하지만 반드시 태그를 사용할 필요는 없습니다.

      import { useActionState, useRef } from "react";
      
      function Form({ someAction }) {
        const ref = useRef(null);
        const [state, action, isPending] = useActionState(someAction);
      
        async function handleSubmit() {
          // See caveats below
          await action({ email: ref.current.value });
        }
      
        return (
          <div>
            <input ref={ref} type="email" name="email" disabled={isPending} />
            <button onClick={handleSubmit} disabled={isPending}>
              Submit
            </button>
            {state.errorMessage && <p>{state.errorMessage}</p>}
          </div>
        );
      }

      #1-3 장점

      두가지 (① 반환값, ② 래핑된 함수의 pending 상태) 를 자동으로 트래킹한다는 점이 장점입니다.


      달라진점 #2 : ReactDOM의 Actions

      • 기존처럼 태그의 action 속성에 URI를 넘겨주게 되면,

        • 기본 HTML의 태그와 동일하게 동작합니다.

      • 기존과 달리 태그의 action 속성에 비동기함수를 넘겨주게 되면,

        • form 태그의 필드들을 자동으로 초기화시켜줍니다.

      <form action={actionFunction}>


      달라진점 #3 : ReactDOM의 useFormStatus 훅

      • 기존에도 Context를 통해 수행할 수 있었지만, 더 쉽게 작동하는 useFormStatus 훅입니다.

      • 태그 하위 컴포넌트에서 상위 요소인 form의 정보를 접근할 수 있도록 합니다.

      import {useFormStatus} from 'react-dom';
      
      function DesignButton() {
        const {pending} = useFormStatus();
        return <button type="submit" disabled={pending} />
      }

      #3-1 레퍼런스

      • parameter ⇒ 없음

      • returns ⇒ 다음과 같은 속성을 가진 객체를 반환합니다.

        • pending : true값이면 부모의 pending이 성공, false값이면 실패를 의미합니다.

        • data : 부모 이 전송중인 데이터를 포함한 formData.

        • method : ‘get’이나 ‘post’ 중 하나. 부모 이 HTTP 메서드를 잘 전송했는지를 나타냅니다.

        • action : 부모 에 action 속성이 적용된 비동기 함수

      #3-2 사용

      form이 제출되는 동안 대기상태를 보여주기 위해, useFormStatus 훅을 사용할 수 있습니다.

      태그에 렌더링된 컴포넌트에서 useFormStatus를 호출하고 있고, 이는 반환된 대기상태 속성을 읽습니다.

      import { useFormStatus } from "react-dom";
      import { submitForm } from "./actions.js";
      
      function Submit() {
        const { pending } = useFormStatus();
        return (
          <button type="submit" disabled={pending}>
            {pending ? "Submitting..." : "Submit"}
          </button>
        );
      }
      
      function Form({ action }) {
        return (
          <form action={action}>
            <Submit />
          </form>
        );
      }
      
      export default function App() {
        return <Form action={submitForm} />;
      }

      위 예제는 한 눈에 보기 쉽게 버튼 텍스트로 pending 상태를 확인할 수 있는 예제입니다 !


      달라진점 #4 : useOptimistic 훅

      비동기(async) 요청이 진행되는 동안, 최종 상태만을 낙관적으로 보여주는 UI 패턴이 있습니다.


      React 19버전에서는 useOptimistic 훅을 사용해서 쉽게 만들었다고 합니다

      • 비동기 호출이 성공했을 경우를 가정하고 변경사항을 화면에 업데이트 합니다.

        • 예를들어서 Youtube의 실시간 채팅 같은 경우, 내가 텍스트를 입력하고 엔터를 눌렀을 때

        • 실제로 채팅 서버에 올라가는 시간은 다르지만 엔터를 누름과 동시에 나의 화면(UI)에서는 마치 바로 보내진 것처럼 보여지는 것과 같다고 볼 수 있을 것 같습니다!

      const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);

      #4-1 레퍼런스

      • parameter

        • state : 초기에 반환되는 값

        • updateFn(currentState, optimisticValue) : 현재 상태를 나타내는 current state, 그리고 addOptimistic을 통해 설정된 optimisticValue를 갖는 함수입니다.

      • returns

        • optimisticState : action이 대기상태가 아니면 state, 대기상태면 updateFn을 통해 반환된 값

        • addOptimistic : 낙관적인 업데이트가 발생했을 때 호출하는 dispatch 함수입니다

      #4-2 사용

      네트워크 요청과 같은 백그라운드 작용이 완성되기 전에, UI 업데이트를 낙관적으로 하는 방법을 제시합니다.

      • 앱 사용에서 더 부드러움을 느낄 수 있습니다

      • form을 제출한 이후, 변화를 적용하기 위해 서버 응답을 기다리기보다는 기대되는 결과물을 미리 UI에 적용합니다.

      import { useOptimistic, useState, useRef } from "react";
      import { deliverMessage } from "./actions.js";
      
      function Thread({ messages, sendMessage }) {
        const formRef = useRef();
        async function formAction(formData) {
          addOptimisticMessage(formData.get("message"));
          formRef.current.reset();
          await sendMessage(formData);
        }
        const [optimisticMessages, addOptimisticMessage] = useOptimistic(
          messages,
          (state, newMessage) => [
            ...state,
            {
              text: newMessage,
              sending: true
            }
          ]
        );
      
        return (
          <>
            {optimisticMessages.map((message, index) => (
              <div key={index}>
                {message.text}
                {!!message.sending && <small> (Sending...)</small>}
              </div>
            ))}
            <form action={formAction} ref={formRef}>
              <input type="text" name="message" placeholder="Hello!" />
              <button type="submit">Send</button>
            </form>
          </>
        );
      }
      
      export default function App() {
        const [messages, setMessages] = useState([
          { text: "Hello there!", sending: false, key: 1 }
        ]);
        async function sendMessage(formData) {
          const sentMessage = await deliverMessage(formData.get("message"));
          setMessages((messages) => [...messages, { text: sentMessage }]);
        }
        return <Thread messages={messages} sendMessage={sendMessage} />;
      }

      Send 버튼을 누르면, 버튼 “Send”가 “Sending…”으로 바뀌어서 마치 서버가 바로 응답한 것 처럼 보이게 하는 효과입니다.


      달라진점 #5 : use API

      React 19에서 새로운 API로 “use”를 공개했습니다. promise 객체와 context를 읽을 수 있습니다.

      • 기존에도 useContext를 통해 가능하긴 했지만, 차이점은 use의 경우 if문처럼 조건문에서도 수행가능하다는 점이 다릅니다.

      #5-1 레퍼런스

      import { use } from 'react';
      
      function MessageComponent({ messagePromise }) {
        const message = use(messagePromise);
        const theme = use(ThemeContext);
        // ...

      #5-2 사용

      function HorizontalRule({ show }) {
        if (show) {
          const theme = use(ThemeContext);
          return <hr className={theme} />;
        }
        return false;
      }

      if 문 안에서 use가 사용되어, Context 값을 조건적으로 읽을 수가 있습니다.


      마치며 ..

      React 공식문서를 이렇게나 깊게 파고들은 건 처음인데, 새롭게 알게된 지식도 많았고

      데보션에 글까지 완성하여 올리니 뿌듯함이 더해지는 것 같습니다.


      종종 공부한 내용을 토대로 올려보겠습니다!

      오늘도 긴 글 읽어주셔서 감사드립니다.


      이상으로 데보션영 3기 정세희였습니다!

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      say 님의 최신 블로그

      더보기
      동영상 기고하기