[7주차] Props와 State
3월 2일 자 학습 내용 정리입니다.
✅ Props
Props(Properties)는 컴포넌트에 원하는 값을 넘겨줄 때 사용한다.
넘겨줄 수 있는 값은 변수, 함수, 객체, 배열 등 JavaScript의 요소라면 모두 가능하다.
Props는 주로 컴포넌트의 재사용을 위해 사용된다.
// --- Pokemon.js ---
import React from 'react';
const Pokemon = ({ name, type }) => {
return (
<div>
선택한 포켓몬은 {name}이며,
{type}타입 포켓몬입니다.
</div>
);
}
export default Pokemon;
// --- App.js ---
import React from 'react';
import Pokemon from './Pokemon';
const App = () => {
return (
<div>
<Pokemon name='파이리' type='불' />
<Pokemon name='이상해씨' type='풀' />
<Pokemon name='피카츄' type='전기' />
</div>
);
}
export default App;
Props 사용 시 주의해야할 점은 Props는 읽기 전용이라는 것이다.
따라서 Props의 값을 임의로 변경할 수는 없으며 Props의 값을 변경해 사용해야 할 경우 새로운 변수에 할당해야 한다.
// 올바르지 않은 Props 사용
const Pokemon = (props) => {
props.type = props.type + '타입'; // X
return (
<div>
선택한 포켓몬은 {props.name}이며,
{props.type} 포켓몬입니다.
</div>
);
}
// 올바른 Props 사용
const Pokemon = (props) => {
const newTypeText = props.type + '타입'; // O
return (
<div>
선택한 포켓몬은 {props.name}이며,
{newTypeText} 포켓몬입니다.
</div>
);
}
✅ State
State는 컴포넌트 내에서 유동적으로 변할 수 있는 값을 저장한다.
이는 개발자가 의도한 동작에 의해 변할 수도 있고 사용자의 입력에 따라 새로운 값으로 변경될 수도 있다.
State을 선언하기 위해서는 React의 useState을 import해야 한다.
useState의 구성은 다음과 같다.
import { useState } from 'react';
const [state, setState] = useState(initialValue);
state는 값을 사용할 때 쓰고 setState은 state의 값을 변경할 때 쓴다.
state 선언 시 useState의 인자로 초기값을 넘길 수 있다.
State 값이 변경되고 재렌더링이 필요한 경우 React가 자동으로 계산해 변경된 부분을 렌더링한다.
setState로 State의 값을 변경하는 작업을 통해 React가 컴포넌트를 재렌더링해야 한다는 것을 알 수 있다.
state의 값을 임의로 state을 사용해 변경할 경우에는 재렌더링이 필요하다는 것을 알기 어렵다.
따라서 state의 값을 변경할 때에는 반드시 setState를 통해 값을 변경해야 한다.
setState를 사용해 State의 값을 변경하는 방법은 두 가지가 있다.
첫째로 setState 함수에 변경할 값을 직접 넣는 것이다.
const [count, setCount] = useState(0);
setCount(count + 1);
둘째로 setState 함수에 함수를 넣는 것이 있다.
const [count, setCount] = useState(0);
setCount((cur) => cur + 1);
이 경우 함수가 반환하는 값으로 State가 변경되며 이는 현재 값을 기반으로 State를 변경하고자 하는 경우에 권장된다.
State에 Object를 넣는 경우에는 주의할 점이 있다.
const [cat, setCat] = useState({name:'무', age:'4'})
setCat((cur) => {
cur.name = '조';
return cur;
});
위의 경우 object 내의 value를 setState를 사용해 바꿨음에도 불구하고 이 변동사항은 React가 감지하지 못한다.
왜냐하면 object 자체가 변경되지는 않았기 때문이다.
따라서 React의 입장에서는 state가 변경되지 않았기 때문에 재렌더링이 일어나지 않는다.
const [cat, setCat] = useState({name:'무', age:'4'})
setCat((cur) => {
const newCat = {...cur};
newCat.name = '조';
return newCat;
});
따라서 재렌더링이 이루어지도록 하려면 변경된 object를 새로운 object에 담아 setState에 새로운 object를 넘겨야 한다.
이 경우에는 newCat으로 state가 변경되었기 때문에 React가 변동사항을 감지할 수 있다.
