ReactNextCentral

상호작용성 추가하기

Published on
이 장에서는 리액트에서 상호작용을 다루고 상태를 업데이트하여 다양한 출력을 관리하는 방법을 배우게 됩니다.

화면의 일부 요소는 사용자 입력에 응답하여 업데이트됩니다. 예를 들어, 이미지 갤러리를 클릭하면 활성 이미지가 변경됩니다. 리액트에서 시간이 지남에 따라 변경되는 데이터를 상태(state)라고 합니다. 모든 컴포넌트에 상태를 추가하고 필요에 따라 업데이트할 수 있습니다. 이 장에서는 상호 작용을 처리하고 상태를 업데이트하며 시간에 따라 다른 출력을 표시하는 컴포넌트를 작성하는 방법을 배우게 될 것입니다.

이 장에서 배우는 내용

이벤트에 응답하기

리액트에서는 JSX에 이벤트 핸들러를 추가할 수 있습니다. 이벤트 핸들러는 클릭, 호버, 폼 입력에 포커스 등과 같은 사용자 상호 작용에 응답하기 위해 작성하는 사용자 정의 함수입니다.

<button>과 같은 내장된 컴포넌트는 onClick과 같은 내장된 브라우저 이벤트만 지원합니다. 그러나 사용자 정의 컴포넌트를 생성하고, 해당 이벤트 핸들러에는 애플리케이션에 특정한 이름을 지정할 수도 있습니다.

상태(state): 컴포넌트의 메모리

컴포넌트는 종종 상호 작용의 결과로 화면에 표시되는 내용을 변경해야 합니다. 폼에 입력을 입력하면 입력 필드가 업데이트되어야 하고, 이미지 캐러셀에서 "다음"을 클릭하면 표시되는 이미지가 변경되어야 하며, "구매"를 클릭하면 제품이 장바구니에 추가되어야 합니다. 컴포넌트는 "기억"해야 하는 내용이 있어야 합니다. 현재 입력 값, 현재 이미지, 장바구니 등이 그러한 컴포넌트별 메모리인 상태(state)입니다.

useState Hook을 사용하여 컴포넌트에 상태를 추가할 수 있습니다. Hook은 컴포넌트가 리액트 기능(상태는 그 중 하나)을 사용할 수 있도록 하는 특별한 함수입니다. useState Hook을 사용하면 상태 변수를 선언할 수 있습니다. 초기 상태를 가져와 현재 상태와 상태 업데이트 함수를 반환하는 쌍의 값을 얻을 수 있습니다.

const [index, setIndex] = useState(0);
const [showMore, setShowMore] = useState(false);

다음은 이미지 갤러리에서 상태를 사용하고 업데이트하는 방법입니다.

렌더링과 커밋

컴포넌트가 화면에 표시되기 전에 리액트에 의해 렌더링되어야 합니다. 이 과정의 단계를 이해하면 코드의 실행 방식을 생각하고 동작을 설명하는 데 도움이 됩니다.

컴포넌트가 재료로부터 맛있는 요리를 조리하는 주방의 요리사라고 상상해 보세요. 이 시나리오에서 리액트는 손님의 주문을 받아 주방에 전달하고 그들에게 주문을 가져오는 웨이터입니다. UI를 요청하고 제공하는 이 과정에는 세 가지 단계가 있습니다.

  1. 렌더링 트리거 (손님의 주문을 주방에 전달)
  2. 컴포넌트 렌더링 (주방에서 주문을 준비)
  3. DOM에 커밋 (주문을 테이블에 올리기)

스냅샷으로서의 상태(state)

일반적인 자바스크립트 변수와 달리 리액트 상태(state)는 스냅샷과 유사하게 작동합니다. 상태를 설정하면 이미 있는 상태 변수가 변경되지 않고 다시 렌더링이 트리거됩니다. 처음에는 이 동작이 놀라울 수 있습니다!

console.log(count); // 0
setCount(count + 1); // 1로 다시 렌더링을 요청
console.log(count); // 여전히 0!

이 동작은 암묵적인 버그를 피할 수 있도록 도와줍니다. 다음은 간단한 채팅 앱의 예시입니다. "Send"를 누르고 나서 수신자를 "Bob"으로 변경하면 5초 후에 어떤 이름이 알림에 표시될까요?

여러 개의 상태 업데이트를 큐에 저장하기

이 컴포넌트는 버그가 있습니다. "더하기 3"을 클릭하면 점수가 한 번만 증가합니다.

상태는 스냅샷으로서에서 이런 현상이 발생하는 이유에 대해 설명합니다. 상태를 설정하면 새로운 렌더링을 요청하지만 이미 실행 중인 코드에서는 변경되지 않습니다. 따라서 setScore(score + 1)를 호출한 후에도 점수는 여전히 0으로 유지됩니다.

console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0

이를 해결하기 위해 상태를 설정할 때 업데이트 함수를 전달할 수 있습니다. setScore(score + 1)setScore(s => s + 1)로 바꾸면 "더하기 3" 버튼이 제대로 작동합니다. 이를 통해 여러 상태 업데이트를 큐에 저장할 수 있습니다.

상태에서 객체 업데이트하기

상태는 객체를 포함한 모든 종류의 자바스크립트 값으로 유지할 수 있습니다. 그러나 리액트 상태에서 직접 객체와 배열을 변경해서는 안 됩니다. 객체와 배열을 업데이트하려면 새로운 객체를 생성하거나(또는 기존 객체의 사본을 만들거나) 상태를 새로운 객체를 사용하도록 업데이트해야 합니다.

보통은 ... 전개 구문을 사용하여 변경하려는 객체와 배열을 복사합니다. 예를 들어, 중첩된 객체를 업데이트하는 방법은 다음과 같습니다.

코드에서 객체를 복사하는 작업이 지루하다면, Immer와 같은 라이브러리를 사용하여 반복적인 코드를 줄일 수 있습니다.

상태에서 배열 업데이트하기

배열은 상태에 저장할 수 있는 또 다른 유형의 변경 가능한 자바스크립트 객체이며 읽기 전용으로 처리해야 합니다. 객체와 마찬가지로 상태에 저장된 배열을 업데이트하려면 새로운 배열을 생성하거나(또는 기존 배열의 사본을 만들거나) 상태를 새 배열을 사용하도록 설정해야 합니다.

코드에서 배열을 복사하는 작업이 지루하다면, Immer와 같은 라이브러리를 사용하여 반복적인 코드를 줄일 수 있습니다.

다음에 알아보기

이벤트에 응답하기

이벤트 핸들러를 사용하여 리액트에서 사용자 상호작용에 대한 응답을 정의하고, 이벤트 핸들러를 컴포넌트에 전달하고 관련된 주의사항과 전파에 대한 이해를 제공하는 가이드입니다.

View

State: 컴포넌트 기억 공간

리액트 컴포넌트에서 상태(state)를 다루는 방법과 useState Hook을 활용하는 방법에 대한 기본적인 내용을 다룹니다.

View

렌더링과 커밋

리액트에서 렌더링 및 DOM 업데이트 과정을 이해하고, 초기 렌더링과 상태 업데이트를 통한 재렌더링, 그리고 DOM 커밋 단계를 파악합니다.

View

State를 스냅샷으로 사용

리액트에서 상태(State)를 스냅샷으로 사용하는 방법에 대해 설명합니다. 리액트에서 상태를 업데이트하면 새로운 렌더링이 트리거되며, 이러한 동작을 자세히 살펴봅니다.

View

여러 State 연속 업데이트

상태 업데이트를 일괄 처리하며, 동일한 상태 변수를 여러 번 업데이트하려면 업데이터 함수를 사용하는 방법을 이해합니다.

View

State에서 객체 업데이트

리액트에서 객체를 상태로 사용할 때, 객체를 직접 변이시키지 말고 항상 새로운 객체를 생성하여 상태로 설정해야 합니다.

View

State에서 배열 업데이트

리액트에서 배열을 업데이트할 때는 상태를 직접 변이시키지 말고 새로운 배열을 생성하여 상태를 업데이트해야 합니다.

View