2 분 소요

React State&Props


Props

특징

  • 컴포넌트의 속성을 의미하며, 외부로부터 전달받은 값은로 웹 어플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다.
  • 부모 컴포넌트로부터 전달받은 값이다.
    • 컴포넌트를 함수처럼 생각하면, 이는 함수의 전달인자와 같고, 이 함수의 데이터 초기값이 된다.
  • 객체이다.
  • 읽기 전용이다.
    • props는 함부로 변경될 수 없는 읽기 전용 객체이다.
    • 만약 읽기 전용 객체가 아니라면 부모 컴포넌트의 값에 영향을 미칠 수 있게 되고 React의 단방향, 하향식 데이터 흐름 원칙에 위배되기 때문에 그렇다.

어떻게 사용할까

  1. 하위 컴포넌트에 전달하고자 하는 값과 속성을 정의한다.
  2. props를 이용하여 정의된 값과 속성을 전달한다.
  3. 전달받은 props를 렌더링한다.

Ex

function Parent() {
  const child_value = "props" // 1
  
  
  return (
  	<div className="Parent">
    	<Child value={child_value}/>  // 2
		</div>
  )
}

function Child(props) {
  return (
  	<div className="Child">
    	<p>{props.value}</p> // 3
    </div>
  )
}

2번의 다른 전달 방법으로는 여는 태그와 닫는 태그 사이에 value를 넣어 전달할 수 있고, 이는 props.children으로 해당 value에 접근가능하다.

Ex.

function Parent() {
  const child_value = "props" // 1
  
  
  return (
  	<div className="Parent">
    	<Child>{child_value}</Child>  // 2
		</div>
  )
}

function Child(props) {
  return (
  	<div className="Child">
    	<p>{props.children}</p> // 3
    </div>
  )
}

State

State란 체크박스의 체크 여부와 같이 해당 컴포넌트 내에서 변할 수 있는 값이다.

State Hook, useState


React에서는 state를 다루는 방법 중 하나로 useState라는 함수를 사용한다.

선언 예시는 다음과 같다.

//1. 우선 useState를 사용하기 위해 React의 useState를 import 해준다
import {useState} from "react";

//2. 이후 useState를 컴포넌트 안에서 호출한다.
//이때, 호출은 변수 선언과 같으며, 이 State 변수는 React에 의해 함수가 끝나도 사라지지 않는다.
function StateExample() {
  const [isChecked, setIsChecked] = useState(false);
  // 여기서 isChecked는 현재 상태 변수이고, setIsChecked는 이 상태값을 갱신할 수 있는 함수이다. useState()의 괄호 안은 상태 초기값이 들어간다.
  //  -> const [state 저장 변수, state 갱신 함수] = useState(상태 초기값)
}

위와 같이 선언을 하고 나면, 상태값 갱신 함수를 통해 상태값을 갱신할 수 있다.

체크박스를 활용한 예시는 다음과 같다.

function StateCheckExample() {
  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는 항상 상태 변경 함수 호출로 변경해줘야 한다.
    • 강제로 변경 시, 리렌더링이 되지 않는다거나 state가 제대로 변경되지 않는다.
  • useState의 경우, 참조하고 있는 값의 메모리가 바뀌어야 해당 컴포넌트가 리렌더링되기 때문에 변수를 할당하는 과정이 중요하다.

데이터 흐름


위에서 간략하게 말한것과 같이 리액트는 “단방향 데이터 흐름”이다.

  • 우선 리액트의 개발 방식은 컴포넌트 단위의 개발이다.
    • 따라서 리액트를 사용하여 애플리케이션을 구축할 경우, 컴포넌트의 계층 구조를 나눠야 한다.
    • 또한 이러한 계층 구조는 트리형이고 데이터는 트리의 root로부터 내려가는 흐름을 가지게 되어야한다.
    • 이러한 방식은 데이터를 감지하는데 부담이 적고, 흐름 또한 단순하기 때문에 가독성이나 유지보수를 편리하게 할 수 있다.
  • 따라서 각 컴포넌트는 특정 컴포넌트의 state 유무를 알 수 없다.

State 끌어올리기

그러나 만약 하나의 컴포넌트에서 사용한 State가 다른 컴포넌트에서도 필요하다면 다른 컴포넌트간의 state를 동기화 하는 대신에 가장 가까운 공통 부모로 State를 끌어올릴 수 있다.

체크박스를 활용한 예시는 다음과 같다.

import {useState} from "react";

//부모 컴포넌트
function Parent() {
  const child_value = "props";
  const [isChecked, setIsChecked] = useState(false);
  
  //자식 컴포넌트의 check여부를 가져올 함수
  function handleChecked(event) => {
    setIsChecked(event.target.checked);
  }
  
  
  return (
  	<div className="Parent">
    	<Child
    		state_value = {child_value}
				state_function = {handleChecked} //자식 컴포넌트의 state를 동기화 시키기 위한 함수 전달
			/>
      <span>{isChecked ? "Checked" : "Unchecked"}</span>
		</div>
  )
}

function Child1(props) {
  return (
		<div className="APP">
    	<input type="checkbox" checked={isChecked} onChange={handleChecked} /> 
		</div>
  )
}

State&Props를 활용한 예제

본 포스팅은 코드스테이츠 BEB 과정을 수강하며 작성한 글입니다.

Reference
https://ko.reactjs.org/docs/lifting-state-up.html
https://ko.reactjs.org/docs/state-and-lifecycle.html#the-data-flows-down