[React] State&Props , 데이터 흐름 , State 끌어올리기
React State&Props
Props
특징
- 컴포넌트의 속성을 의미하며, 외부로부터 전달받은 값은로 웹 어플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다.
- 부모 컴포넌트로부터 전달받은 값이다.
- 컴포넌트를 함수처럼 생각하면, 이는 함수의 전달인자와 같고, 이 함수의 데이터 초기값이 된다.
- 객체이다.
- 읽기 전용이다.
- props는 함부로 변경될 수 없는 읽기 전용 객체이다.
- 만약 읽기 전용 객체가 아니라면 부모 컴포넌트의 값에 영향을 미칠 수 있게 되고 React의 단방향, 하향식 데이터 흐름 원칙에 위배되기 때문에 그렇다.
어떻게 사용할까
- 하위 컴포넌트에 전달하고자 하는 값과 속성을 정의한다.
- props를 이용하여 정의된 값과 속성을 전달한다.
- 전달받은 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>
)
}
본 포스팅은 코드스테이츠 BEB 과정을 수강하며 작성한 글입니다.
Reference
https://ko.reactjs.org/docs/lifting-state-up.htmlhttps://ko.reactjs.org/docs/state-and-lifecycle.html#the-data-flows-down