[React] React State & Props
props
- 외부(부모 컴포넌트)로부터 전달받은 값. (ex. 이름, 성별 ··· )
- 컴포넌트의 속성(property)을 의미한다.
- 객체 형태
- 변경되지 않음. 읽기 전용! → Side Effect
- 초깃값으로 사용할 수 있다.
/* 사용 방법 예시 */
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child attribute={value} /> // 1.하위 컴포넌트에 전달하고자 하는 속성을 정의
</div>
);
};
function Child(props) { // 2.props를 이용하여 정의된 값과 속성을 전달
return (
<div className="child">
<p>{props.text}</p> // 3.전달받은 props를 렌더링
</div>
);
};
/* props를 전달하는 또 다른 방법 예시 */
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child>I'm the eldest child</Child> //여는 태그와 닫는 태그의 사이에 value를 넣어
</div>
);
};
function Child(props) {
return (
<div className="child">
<p>{props.children}</p> //props.children을 이용해 전달
</div>
);
};
state
- (컴포넌트) 내부에서 변화하는 값. (ex. 나이, 주소, 토글 스위치, 장바구니 물건 선택 ··· )
(참고) Controlled Component : state를 통제할 수 있는 컴포넌트
/* useState 사용법 예시 */
import { useState } from "react"; // useState 불러오기 *
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false); // useState 를 컴포넌트 안에서 호출
const handleChecked = (event) => {
setIsChecked(event.target.checked); // state 변수를 갱신할 수 있는 함수 호출
};
return (
<div className="App">
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>
);
}
export default CheckboxExample;
→ useState를 호출한다는 것은 "state"라는 변수를 선언하는 것과 같다.
이 변수의 이름은 어떤 것이든 상관이 없으며, 위 예시에서는 isChecked를 사용하고 있다.
(참고) 일반적인 변수와 달리 state변수는 리액트에 의해 함수가 끝나도 사라지지 않는다.
→ 여기서 isChecked, setIsChecked는 useState의 리턴값을 구조 분해 할당한 변수이다.
const [isChecked, setIsChecked] = useState(false);
// 위 코드를 풀어쓰면 아래와 같다.
const stateHookArray = useState(false);
const isChecked = stateHookArray[0];
const setIsChecked = stateHookArray[1];
// 수도 코드
const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
- state hook 사용 시 주의점
1. React 컴포넌트는 state가 변경될 때마다 새롭게 호출되고, 리렌더링 된다.
2. React state는 상태 변경 함수 호출로 변경해야 한다. 그냥 정해진 약속임!
>> 리액트에서 이벤트 처리하기
- 이벤트는 소문자 대신 카멜 케이스(camelCase)를 사용
- 문자열이 아닌 함수로 이벤트 처리 함수(Event handler)를 전달
// HTML 예시
<button onclick="handleEvent()">Event</button>
// React 예시
<button onClick={handleEvent}>Event</button>
onChange
: input 의 텍스트가 바뀔 때마다 발생하는 이벤트
onClick
: 클릭했을 때 발생하는 이벤트
/* 사용 예시 */
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value); //e.target.value를 통해 이벤트 객체에 담겨있는 input값을 읽어올 수 있음
}
const handleClick = () => { //onClick 관련 함수
alert(name);
};
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={handleClick}>Button</button> //함수 자체를 전달!
//onClick={alert(name)} 이렇게 사용X
<h1>{name}</h1>
</div>
)
};
//onChange 이벤트가 발생하면, handleChange함수가 작동하여
//이벤트 객체에 담긴 input값을 setState를 통해 새로운 state로 갱신함.
● React 데이터 흐름
- 리액트 데이터는 하향식(top-down)이며, 단방향(one-way data flow)이다.
즉, 부모 컴포넌트가 데이터를 전달하는 주체이다.
(참고) 컴포넌트 기반의 개발은 상향식(bottom-up)이라고 할 수 있다.
상향식의 개발의 장점으로는 테스트가 쉽고 확장성이 좋다는 점이 있다.
▶ 어떤 데이터를 state로 두어야 할까?
- 부모로부터 props를 통해 전달되지 않는 것
- 변하는 것
- 컴포넌트 안의 다른 state나 props로 계산할 수 없는 것
▶ state의 위치 정하기
- 하나의 state를 기반으로 두 컴포넌트가 영향을 받는 경우, 공통의 부모를 찾아 그 곳에 state를 위치시켜야 한다.