[ State로 상태 관리하기]
하나의 컴포넌트에 여러 개의 state를 만들 수 있음
리렌더링 (Re-Rendering) : 컴포넌트의 state 값이 바뀌면 그 컴포넌트가 return 을 다시 해서 화면을 다시 그림
이 때, 변경된 state 값도 함께 반영
1. 새로운 state를 생성하는 useState라는 함수는 인수로 초깃값을 받아서 두 개의 요소를 담은 배열을 반환하는데 첫 번째 요소는 state의 현재 값이고 두 번째 요소는 state를 변경시키는 상태변화함수이다.
2. useState() 생성 시 괄호 안에 값을 넣어 state 값을 생성할 수 있다.
그런데 그냥 변수 하나 만들어서 관리하면 그게 state랑 똑같은 거 아님?
=> 그렇게 하면 버튼이 클릭될때마다 변수의 값이 바뀔 순 있음
그렇지만, 변수의 값이 바뀐다고 컴포넌트 리렌더링 되진 않음
그래서 아무리 버튼을 클릭해도 아무 변화도 일어나지 않음
[ State와 Props]
1. 25번째 줄의 light state가 바뀌게 되면 Blob 컴포넌트도 리렌더링 됨
=> 리액트 컴포넌트들은 자신이 갖는 state가 변경되지 않아도
부모로부터 받는 props의 값이 바뀌게 되면 리렌더링이 발생
< 리액트 컴포넌트가 리렌더링되는 상황 >
1. 자신이 관리하는 state의 값이 변경될 때
2. 자신이 제공받는 props의 값이 변경될 때
3. 부모 컴포넌트가 리렌더링 되면 자식 컴포넌트도 리렌더링
+버튼을 누르면 count state가 변경되면서 App 컴포넌트가 가진 state가 변경되므로 리렌더링이 일어남 (1번)
→ App의 자식 컴포넌트인 Blub 컴포넌트의 리렌더링이 일어남 (3번)
→ +버튼을 누를 때(count state가 변경될 때)마다 전혀 상관없는 Blub 컴포넌트의 리렌더링이 일어남
→ 이걸 방지하기 위해 관련이 없는 두 개의 state를 서로 다른 컴포넌트로 분리함 (사진)
이렇게 되면 App 컴포넌트에 count, light state가 같이 존재하는게 아니라
Counter 컴포넌트에 count state, Blub 컴포넌트에 light state가 존재하기 때문에
각각의 state가 변화하더라도 각 컴포넌트만 리렌더링하게 됨
[ State로 사용자 입력 관리하기 ]
< 간단한 회원가입 폼 만들기 >
이제 중복되는 코드를 제거해보자.
'name, birth, country, bio' 각각의 state를 관리하는 것보다 하나의 객체로 만들고
하나의 state로 만들어서 관리하도록 구현.
import { useState } from "react";
//간단한 회원가입 폼
const Register = () => {
const[input, setInput] = useState({
name : "",
birth: "",
country: "",
bio: "",
});
const onChangeName = (e) => {
setInput({
// 관련 없는 값들은 그대로 유지
...input,
name: e.target.value
})
};
const onChangeBirth = (e) => {
setInput({
...input,
birth: e.target.value
})
};
const onChangeCountry = (e) => {
setInput({
...input,
country: e.target.value
})
}
const onChangeBio = (e) => {
setInput({
...input,
bio: e.target.value
})
}
return (
<div>
<div>
<input value={input.name} onChange={onChangeName} placeholder={"이름"}></input>
</div>
<div>
<input value={input.birth} onChange={onChangeBirth} type="date"></input>
</div>
<div>
<select value={input.country} onChange={onChangeCountry}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
{input.country}
</div>
<div>
<textarea value={input.bio} onChange={onChangeBio}></textarea>
</div>
</div>
);
};
export default Register;
그리고 상태를 변경할 때
Spread 연산자를 통해 변경하지 않는 값들은 그대로 유지시키고 변경할 값만 넣어주었는데,
여전히 반복되는 코드들이 존재함 (onChange~의 반복)
import { useState } from "react";
//간단한 회원가입 폼
const Register = () => {
const[input, setInput] = useState({
name : "",
birth: "",
country: "",
bio: "",
});
// 통합이벤트핸들러
const onChange = (e) => {
setInput({
...input,
[e.target.name] : e.target.value,
})
}
return (
<div>
<div>
<input name="name" value={input.name} onChange={onChange} placeholder={"이름"}></input>
</div>
<div>
<input name="birth" value={input.birth} onChange={onChange} type="date"></input>
</div>
<div>
<select name="country" value={input.country} onChange={onChange}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
{input.country}
</div>
<div>
<textarea name="bio" value={input.bio} onChange={onChange}></textarea>
</div>
</div>
);
};
export default Register;
그래서 onChange라는 이벤트 핸들러를 만들고 객체를 만들어서 전달할 때
name 자리에 점표기법을 이용하여 변수로 넣을 수 있도록 함.
결과적으로 코드의 양이 훨씬 줄어든 것을 확인할 수 있음.
'한 입 크기로 잘라먹는 React' 카테고리의 다른 글
7. 실습 : 카운터 앱 만들기 (0) | 2024.06.01 |
---|---|
5. React.js의 useRef (0) | 2024.05.31 |
3. React.js 입문 (0) | 2024.05.30 |
2. React.js (0) | 2024.05.30 |
1. Node.js 기초 (0) | 2024.05.30 |