본문 바로가기
개발이야기/React

useActionState, useEffectEvent

by dev.josh 2025. 12. 15.
반응형

1. useActionState란?

폼 액션(Form Action)의 결과에 따라 상태를 업데이트하고, 비동기 처리 중인 상태(Pending)까지 한 번에 관리할 수 있게 해주는 React 19의 새로운 훅입니다.

  • 핵심 역할: "서버에 데이터를 보낸 뒤, 그 결과를 화면에 보여주기까지" 필요한 모든 상태 관리를 자동화합니다.

1-1. 기본 문법

const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
  • fn (Action 함수): 폼이 제출될 때 호출될 함수입니다. 이 함수는 첫 번째 인자로 **이전 상태(previousState)**를, 두 번째 인자로 **폼 데이터(formData)**를 받습니다.
  • initialState: 초기 상태값입니다.
  • 반환값:
    1. state: 액션 함수가 반환한 최신 결과값 (초기에는 initialState).
    2. formAction: <form>의 action 속성에 전달할 새로운 액션 함수.
    3. isPending: 비동기 작업이 진행 중인지 알려주는 불리언 값 (로딩 상태 처리용).

 


1-3. 왜 좋은가요? (주요 특징)

  1. 로딩 상태 자동화: setIsLoading(true/false)를 직접 호출할 필요 없이 isPending 하나로 버튼 비활성화나 스피너 표시가 가능합니다.
  2. 데이터 무결성: 폼 액션이 진행되는 동안 이전 상태를 기억하고 있어, 서버 응답이 오기 전까지의 흐름을 안전하게 관리합니다.
  3. 점진적 향상(Progressive Enhancement): (Server Component와 함께 사용 시) 자바스크립트가 브라우저에서 아직 로드되지 않았더라도 폼 제출이 동작하도록 설계되어 있습니다.

 

1-4. 주의사항

  • 첫 번째 인자: 액션 함수(fn)의 첫 번째 인자는 항상 previousState입니다. 일반적인 핸들러 함수와 인자 순서가 다르니 주의해야 합니다.
  • Server Component 궁합: Next.js 같은 프레임워크의 Server Action과 함께 쓸 때 가장 강력한 효과를 발휘합니다.

 

2. useEffectEvent란?

2-1. 정의 및 목적

useEffectEvent는 Effect 내부의 로직 중 '비반응형(non-reactive)' 부분을 따로 분리해낼 때 사용하는 실험적 Hook입니다.

  • 핵심 아이디어: "특정 값이 변경될 때 Effect를 다시 실행하고 싶지는 않지만, 실행될 시점에는 항상 최신 값을 참조하고 싶다"는 문제를 해결합니다.

2-2. 기본 문법

const onSomething = useEffectEvent((arg1, arg2) => {
  // 최신 props나 state를 자유롭게 읽을 수 있음
  console.log(latestState, latestProps);
});

 

2-3. 주요 특징 및 이점

  1. 반응형 로직 vs 비반응형 로직 분리: * useEffect 내부의 로직은 의존성 배열([])에 포함된 값이 바뀔 때마다 실행됩니다.
    • 하지만 useEffectEvent로 감싼 함수는 의존성 배열에 넣을 필요가 없으며(넣어서도 안 됨), 값이 바뀌어도 Effect를 촉발하지 않습니다.
  2. 최신 값 보장: 호출되는 시점에 컴포넌트의 가장 최신 상태값들을 참조하므로, 클로저(Closure) 문제로 인한 '오래된 값(stale value)' 문제를 겪지 않습니다.
  3. 의존성 관리의 간소화: 불필요하게 의존성 배열이 길어지거나, 린트(Lint) 에러를 피하기 위해 억지로 useCallback을 남용할 필요가 없어집니다.

 

2-4. 사용법 예시 (공식 문서 요약)

채팅방에 연결할 때, 연결은 roomId가 바뀔 때만 수행하되 메시지 전송 시에는 최신 theme 설정을 반영하고 싶은 경우입니다.

JavaScript
 
function ChatRoom({ roomId, theme }) {
  // 1. 테마 설정을 읽는 비반응형 로직 추출
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme); // theme이 바뀌어도 Effect는 안 돌지만, 실행 시엔 최신 theme을 씀
  });

  useEffect(() => {
    const connection = createConnection(roomId);
    connection.on('connected', () => {
      onConnected(); // 2. Effect 내부에서 호출
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]); // theme을 의존성 배열에서 제외할 수 있음!
}

 

2-5. 주의 사항 (반드시 지켜야 할 규칙)

  • Effect 내부에서만 호출: 일반 이벤트 핸들러처럼 사용하거나 다른 컴포넌트에 전달하면 안 됩니다. 오직 useEffect 안에서만 호출되어야 합니다.
  • 비동기 전달 금지: 이 함수를 다른 훅이나 컴포넌트의 인자로 넘기지 마세요.
  • 실험적 기능: React 19.2 이상 등 최신 실험적 버전에서 사용 가능하며, 향후 정식 릴리스 전까지 명칭이나 세부 동작이 변경될 수 있습니다.

 

반응형

'개발이야기 > React' 카테고리의 다른 글

Immer  (0) 2026.02.11
ref - DOM 직접 접근 장치  (0) 2025.11.25
이벤트 핸들링  (0) 2025.11.17
컴포넌트  (0) 2025.11.17
render(), virtual DOM, JSX  (0) 2025.11.10