props는 부모 컴포넌트가 자식 컴포넌트에 전달하는 데이터이다. props는 읽기 전용으로 자식 컴포넌트는 props를 수정할 수 없다.
props를 사용하게 되면 컴포넌트 간의 데이터 흐름을 예측 가능하게 만들고, 컴포넌트의 재사용성을 높인다.
state는 컴포넌트 내부에서 관리되는 데이터이다. state는 동적으로 변경될 수 있고 컴포넌트의 렌더링에 영향을 미친다. state를 변경하게 되면 컴포넌트는 다시 렌더링되면서 UI가 업데이트 된다.
state는 주로 사용자 입력이나 네트워크 요청의 응답에 따라 변하는 데이터를 관리할 때 사용된다.
리액트의 단방향 데이터 흐름 원칙 때문!
리액트는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달할 때 단방향으로 전달하도록 설계되었다.
➡️ 컴포넌트 간의 데이터 흐름 예측이 가능하고 일관성 있게 만들 수 있다. 그 결과 애플리케이션 상태 관리가 간단해진다.
props는 읽기 전용이므로 부모 컴포넌트에서 전달된 값이 자식 컴포넌트 내에서 임의로 변경되지 않는다. 따라서 특정 상태가 어디서 어떻게 변했는지를 예측할 수 있다. ➡️ 디버깅 쉬움
props가 변경된다면? 🤔
자식 컴포넌트는 독립적으로 동작하지 않게 되고 재사용이 어려워질 수 있다.
props를 불변으로 유지함으로써 컴포넌트는 외부 입력에만 의존하고 내부적으로는 변경하지 않아서 재사용성이 높아지고 코드의 캡슐화가 된다.
부모 컴포넌트에서 상태로 해당 데이터를 관리하고, 상태 변경 함수를 자식 컴포넌트로 전달하는 방식으로 구현해야 한다. ➡️ 상태 끌어올리기
// 부모 컴포넌트
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<h1>부모 컴포넌트</h1>
<Child count={count} onIncrement={() => setCount(count + 1)} />
</div>
);
}
// 자식 컴포넌트
function Child({ count, onIncrement }) {
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={onIncrement}>카운트 증가</button>
</div>
);
}
count는 props로 내려오고, onIncrement는 부모 상태를 업데이트하는 함수.
자식은 직접 count를 바꾸지 않고, 버튼을 눌러 부모에게 알려주는 역할.