CodeStates/React

[React] State & Props

디스페어 2022. 2. 21.

Props

외부로부터 전달받은 값 즉, 부모 컴포넌트(상위 컴포넌트)로부터 전달받은 값

 

1. Props 특징

  • props를 함수의 전달인자(arguments)처럼 전달받아 이를 기반으로 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환
  • 컴포넌트가 최초 렌더링될 때에 화면에 출력하고자 하는 데이터를 담은 초기값으로 사용 가능
  • props로 어떤 타입의 값도 넣어 전달할 수 있도록 props는 객체의 형태를 가짐
  • 함부로 변경될 수 없는 읽기 전용(read-only) 객체

 

2. Props 사용방법

1. 하위 컴포넌트에 전달하고자 하는 값(data)과 속성을 정의
2. props를 이용하여 정의된 값과 속성을 전달
3. 전달받은 props를 렌더링
  • props 속성의 이름을 임의로 지정 가능
  • props 속성의 이름을 props로 사용할 경우 Syntax Error발생 : 예약어이기 때문
    *컴포넌트 자체의 관점에서 짓는 것을 권장

 

2-1. { props.key }

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

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

export default Parent;
  • props는 객체이고 { key : value }는 Parent 컴포넌트에서 정의한 { attribute : value }의 형태
  • props의 value : dot notation으로 접근 가능

 

2-2. { props.children }

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>
    </div>
  );
}

export default Parent;
  • 여는 태그와 닫는 태그의 사이에 value를 넣어 전달
  • props.children을 이용하여 해당 value에 접근

 

 

State

  • 컴포넌트 사용 중 컴포넌트 내부에서 변할 수 있는 값
  • 상태에 해당하는 데이터를 state로 따로 관리
  • Controlled Component : React가 state를 통제할 수 있는 컴포넌트

 

1. state hook

  • Hook이 나오기 전에는 state는 클래스 컴포넌트에만 다룰 수 있었으나, Hook이 나오면서 함수 컴포넌트도 state를 다룰 수 있게 됨
    *class를 작성하지 않고도 state와 다른 React의 기능들을 사용할 수 있게 해줌

 

1-1. 주의사항

  • React 컴포넌트 : state가 변경되면 새롭게 호출되고, 리렌더링
  • React state는 상태 변경 함수 호출로 변경해야 함
    *강제로 변경해선 안됨

 

1-2. useState

//예시
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>
  );
}

 

1-2-1. React로부터 useState 불러오기

import { useState } from "react";

 

1-2-2. useState를 컴포넌트 안에서 호출하기

function CheckboxExample() {
  const [isChecked, setIsChecked] = useState(false);
  //const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값)
  • isChecked : 새롭게 선언한 state 변수
  • [isChecked, setIsChecked]는 useState의 리턴값을 구조 분해 할당한 변수
    *새로운 state를 선언할 때 배열로 구조 분해 할당하여 사용

 

1-2-3. state 변수에 저장된 값 사용

<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
  • isChecked가 boolean 값을 가지기 때문에 true or false 여부에 따라 다른 결과가 보이도록 삼항연산자를 사용

 

1-2-4. state 갱신하기

const handleChecked = (event) => {
  setIsChecked(event.target.checked);
};
  • state 변수를 갱신할 수 있는 함수인 setIsChecked를 호출

 

 

Event handling

  • React의 이벤트 처리(Event handling) 방식은 DOM과 유사

 

1. React의 이벤트 처리 문법

소문자 대신 카멜 케이스(camelCase) 사용
JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수(Event handler)를 전달
<button onclick="handleEvent()">Event</button>
//HTML의 이벤트 처리 방식

<button onClick={handleEvent}>Event</button>
//React의 이벤트 처리 방식
//onClick={handleEvent()} : 리턴값이 onClick으로 전달되어서 함수 자체가 전달되는 것이 아니라, 
//함수의 결과값이 전달되며 렌더링할 때마다 해당 함수가 호출되기 때문에 성능 이슈가 우려

 

2. 자주 사용되는 이벤트 처리

2-1. onChange

  • input, textarea, select와 같은 폼(Form) 엘리먼트는 사용자의 입력값을 제어하는데, 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state로 관리하고 업데이트
  • onChange : input의 텍스트가 바뀔 때 마다 발생하는 이벤트
function NameForm() {
  const [name, setName] = useState("");

  const handleChange = (e) => {
    setName(e.target.value);
  }
  //onChange 이벤트 발생시 e.target.value를 통해 이벤트 객체에 담겨있는 input 값을 읽어옴
  //이벤트가 발생하면 handleChange 함수가 작동하여 이벤트 객체에 담긴 input값을 setState를 통해 갱신

  return (
    <div>
      <input type="text" value={name} onChange={handleChange}></input>
      //input 태그에 value와 onChange를 넣어줌
      <h1>{name}</h1>
    </div>
  )
};

 

2-2. onClick

  • onClick : 사용자가 클릭이라는 행동을 하였을 때 발생하는 이벤트로 버튼이나 a 태그를 통한 링크 이동 등 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용
  • arrow function을 사용해야 해당 컴포넌트가 가진 state에 함수들이 접근 가능
// 함수 정의하기
return (
  <div>
	...
    <button onClick={() => alert(name)}>Button</button>
	...
  </div>
  );
};

// 함수 자체를 전달하기
const handleClick = () => {
  alert(name);
};

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

 

 

React 데이터

1. 데이터 흐름 VS 웹 어플리케이션 제작 흐름

1-1. 웹 어플리케이션 제작 흐름

  • 상향식(bottom-up) : 프로토타입을 전달받으면 가장먼저 컴포넌트를 찾아 만든 후 페이지를 조립(확장성이 좋음)
    *컴포넌트 : 단일 책임 원칙에 따라 하나의 컴포넌트는 한가지 일만 하도록 구분

 

1-2. 데이터 흐름 : 단방향 데이터 흐름(one-way data flow)

  • 하향식(top-down) : props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 부모 컴포넌트로부터 전달받음
  • 컴포넌트 : props를 통해 전달받은 데이터가 어디서 왔는지 전혀 알지 못합

 

2. 데이터 정의

부모로부터 props를 통해 전달됩니까? state 아님
시간이 지나도 변하지 않나요? state 아님
컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? state아님
  • 모든 데이터를 상태로 둘 필요는 없으며 상태는 최소화하는 것이 좋음
    *상태가 많아질수록 애플리케이션은 복잡해지기 때문

 

3. React에서 데이터 다루기 : state 위치 정하기

  • React에서 데이터를 다룰 때는 컴포넌트들간의 상호 관계와 데이터의 역할, 데이터의 흐름을 고려하여 위치 설정
  • 상태가 특정 컴포넌트에서만 유의미할 경우 특정 컴포넌트에 둠
  • 하나의 상태를 기반으로 두 컴포넌트가 영향을 받을 경우 공통 소유 컴포넌트를 찾아 그 곳에 상태를 위치*두 개의 자식 컴포넌트가 하나의 상태에 접근하고자 할 때는 두 자식의 공통 부모 컴포넌트에 상태를 위치
반응형

댓글