React Props & State / Event

잡초·2023년 3월 24일
post-thumbnail

props

  • 컴포넌트의 속성(property)을 의미한다.
    props는 성별이나 이름처럼 변하지 않는 외부로부터 전달받은 값으로, 웹 애플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다.
  • 부모 컴포넌트(상위 컴포넌트)로부터 전달받은 값이다.
    React 컴포넌트는 JavaScript 함수와 클래스로, props를 함수의 전달인자(arguments)처럼 전달받아 이를 기반으로 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다. 따라서, 컴포넌트가 최초 렌더링 될 때 화면에 출력하고자 하는 데이터를 담은 초깃값으로 사용할 수 있다.
  • 객체 형태이다.
    props로 어떤 타입의 값도 넣어 전달할 수 있도록 props는 객체의 형태를 가진다.
  • props는 읽기 전용이다.
    props는 성별이나 이름처럼 외부로부터 전달받아 변하지 않는 값이다. 그래서 props는 함부로 변경될 수 없는 읽기 전용(read-only) 객체다. 함부로 변경되지 않아야 하기 때문이다.

props 사용법

props를 사용하는 방법은 아래와 같이 3단계 순서로 나눌 수 있다.

  1. 하위 컴포넌트에 전달하고자 하는 값(data)과 속성을 정의한다.
  2. props를 이용하여 정의된 값과 속성을 전달한다.
  3. 전달받은 props를 렌더링한다.
function Parent() {
  return (
    <div className="parent">
      <h1>I'm the parent</h1>
      <Child attribute={value}/> //전달하고자 하는 값을 중괄호 {}를 이용하여 감싼다
    </div>
  );
};

function Child(props) {
  return (
    <div className="child">
      <p>{props.text}</p>
    </div>
  );
};

props는 객체라고 하였고, 이 객체의 { key : value }<Parent> 컴포넌트에서 정의한 { attribute : value }의 형태를 띠게 된다. 따라서 JavaScript에서 객체의 value에 접근할 때 dot notation을 사용하는 것과 동일하게 props의 value 또한 dot notation으로 접근할 수 있다.

props.children

props를 전달하는 또 다른 방법으로 여는 태그와 닫는 태그의 사이에 value를 넣어 전달하는 방법이 있다. 이 경우 props.children을 이용하면 해당 value에 접근하여 사용할 수 있다.

function Parent() {
  return (
    <div className="parent">
        <h1>I'm the parent</h1>
        <Child>I'm the eldest child</Child>
    </div>
  );
};

function Child(props) {
  return (
    <div className="child">
        <p>{props.children}</p>// I'm the eldest child
    </div>
  );
};

State

컴포넌트 내에서 변할 수 있는 값은 React state로 다뤄야 한다.

State hook, useState

useState 사용법

  • useState 를 이용하기 위해서는 React로부터 useState 를 불러와야 한다.
import { useState } from "react";
  • 이후 useState 를 컴포넌트 안에서 호출한다. useState 를 호출한다는 것은 "state" 라는 변수를 선언하는 것과 같으며, 이 변수의 이름은 아무 이름으로 지어도 된다. 일반적인 변수는 함수가 끝날 때 사라지지만, state 변수는 React에 의해 함수가 끝나도 사라지지 않는다.
function CheckboxExample() {
  const [isChecked, setIsChecked] = useState(false);
}
  • useState 를 호출하면 배열을 반환하는데, 배열의 0번째 요소는 현재 state 변수이고, 1번째 요소는 이 변수를 갱신할 수 있는 함수이다. useState 의 인자로 넘겨주는 값은 state의 초깃값이다.
const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);

state 갱신하기

  • state를 갱신하려면 state 변수를 갱신할 수 있는 함수인 setIsChecked 를 호출합니다.

  • 사용자가 체크박스 값을 변경하면 onChange 이벤트가 이벤트 핸들러 함수인 handleChecked 를 호출하고, 이 함수가 setIsChecked 를 호출하게 된다. setIsChecked 가 호출되면 호출된 결과에 따라 isChecked 변수가 갱신되며, React는 새로운 isChecked 변수를 CheckboxExample 컴포넌트에 넘겨 해당 컴포넌트를 다시 렌더링 한다.

function CheckboxExample() {
  const [isChecked, setIsChecked] = useState(false);

  const handleChecked = (event) => {
    setIsChecked(event.target.checked);
  };

  return (
    <div className="App">
      <input type="checkbox" checked={isChecked} onChange={handleChecked} />
      <span>{isChecked ? "Checked!!" : "Unchecked"}</span>
    </div>
  );
}

주의점

React 컴포넌트는 state가 변경되면 새롭게 호출되고, 리렌더링 된다.

Event

React의 이벤트 처리(이벤트 핸들링; Event handling) 방식은 DOM의 이벤트 처리 방식과 유사하다. 단, 몇 가지 문법 차이가 있다.

  • React 에서 이벤트는 소문자 대신 카멜 케이스(camelCase) 를 사용한다.
  • JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수(이벤트 핸들러; Event handler)를 전달한다.

예를 들어 HTML에서 이벤트 처리 방식이 아래와 같다면,

<button onclick="handleEvent()">Event</button>

React의 이벤트 처리 방식은 아래와 같다.

<button onClick={handleEvent}>Event</button>

onChange

<input> <textarea> <select> 와 같은 폼(Form) 엘리먼트는 사용자의 입력값을 제어하는 데 사용된다. React 에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state 로 관리하고 업데이트한다. onChange 이벤트가 발생하면 e.target.value 를 통해 이벤트 객체에 담겨있는 input 값을 읽어올 수 있다. 컴포넌트 return 문 안의 input 태그에 valueonChange 를 넣어주었다. onChangeinput 의 텍스트가 바뀔 때마다 발생하는 이벤트다. 이벤트가 발생하면 handleChange 함수가 작동하며, 이벤트 객체에 담긴 input 값을 setState 를 통해 새로운 state 로 갱신한다.

function NameForm() {
  const [name, setName] = useState("");

  const handleChange = (e) => {
    setName(e.target.value);
  }

  return (
    <div>
      <input type="text" value={name} onChange={handleChange}></input>
      <h1>{name}</h1>
    </div>
  )
};

onClick

onClick 이벤트는 말 그대로 사용자가 클릭이라는 행동을 하였을 때 발생하는 이벤트다. 버튼이나 <a> tag 를 통한 링크 이동 등과 같이 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용하는 이벤트다. 위의 onChange 예시에 버튼을 추가하여 버튼 클릭 시 input tag 에 입력한 이름이 alert을 통해 알림 창이 팝업 되도록 코드를 추가해 보자.

function NameForm() {
  const [name, setName] = useState("");

  const handleChange = (e) => {
    setName(e.target.value);
  }

  return (
    <div>
      <input type="text" value={name} onChange={handleChange}></input>
      <button onClick={alert(name)}>Button</button>//잘못된 방법
      <h1>{name}</h1>
    </div>
  );
};

위와 같이 onClick 이벤트에 alert(name) 함수를 바로 호출하면 컴포넌트가 렌더링 될 때 함수 자체가 아닌 함수 호출의 결과가 onClick 에 적용된다. 때문에 버튼을 클릭할 때가 아닌, 컴포넌트가 렌더링 될 때에 alert 이 실행되고 따라서 그 결과인 undefined (함수는 리턴 값이 없을 때 undefined 를 반환한다.) 가 onClick 에 적용되어 클릭했을 때 아무런 결과도 일어나지 않는다. 따라서 onClick 이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 아래와 같이 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야 한다.

// 함수 정의하기

return (
  <div>
	...
    <button onClick={() => alert(name)}>Button</button>
	...
  </div>
  );
};

// 함수 자체를 전달하기

const handleClick = () => {
  alert(name);
};

return (
  <div>
      ...
    <button onClick={handleClick}>Button</button>
      ...
  </div>
  );
};
profile
개발자가 되고싶은 잡초

0개의 댓글