State란?
- useState() 함수는 리턴 값으로 두 개를 반환한다.
첫 번째 요소는 state로 선언된 변수이고, 두 번째 요소는 상태 변환 함수이다. - 두 개의 값이 있으므로 처음부터 ‘구조 분해 할당’ 을 활용해 배열로 받는것이 일반적이다.
- 리렌더링이란?
- 쉽게 말해 state 값이 변경되면 return을 다시한다. 즉 변경된 state 값으로 화면을 다시 그린다.
App.jsx
import "./App.css";
import { useState } from "react";
function App() {
const [count, setcount] = useState(0);
const [light, setLight] = useState("OFF");
return (
<>
<div>
<h1>{light}</h1>
<button
onClick={() => {
setLight(light === "ON" ? "OFF" : "ON");
}}
>
{light === "ON" ? "끄기" : "켜기"}
</button>
</div>
<div>
<h1>{count}</h1>
<button
onClick={() => {
setcount(count + 1);
}}
>
+
</button>
</div>
</>
);
}
export default App;
- state를 사용하지 않고 일반변수 let light를 만들어서 똑같이 코드를 작성하면 되는 것 아닌가?
- 일반 변수는 ‘리렌더링’이 하지 않기 때문에 화면이 바뀌지 않는다.
- 리액트 컴포넌트는 state 값이 변화될 때만 리렌더링을 하기 때문에 state로 처리해야 한다.
State를 Props로 전달하기
- 리액트에서 리렌더링이 진행되는 경우 세 가지
- 자신이 관리하는 state의 값이 변경 되었을 때
- 자신이 제공받는 props의 값이 변경 되었을 때
- 부모 컴포넌트가 리런데링 되었을 때
- 서로 다른 기능을 하는 두 개의 state를 같은 컴포넌트 안에 넣을 경우, 부모 컴포넌트의 리렌더링으로 인해 상관없는 다른 state 역시 불필요하게 리렌더링 되어 성능 저하를 일으킨다.
- 따라서 기능 별로 컴포넌트를 나누어 관리해야 한다.
Bulb.jsx
import { useState } from "react";
const Bulb = () => {
const [light, setLight] = useState("OFF");
console.log(light);
return (
<div>
{light === "ON" ? (
<h1 style={{ backgroundColor: "orange" }}>ON</h1>
) : (
<h1 style={{ backgroundColor: "gray" }}>OFF</h1>
)}
<button
onClick={() => {
setLight(light === "ON" ? "OFF" : "ON");
}}
>
{light === "ON" ? "끄기" : "켜기"}
</button>
</div>
);
};
export default Bulb;
- 전구를 켜고 끄는 기능
Counter.jsx
import { useState } from "react";
const Counter = () => {
const [count, setcount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button
onClick={() => {
setcount(count + 1);
}}
>
+
</button>
</div>
);
};
export default Counter;
- 버튼을 클릭하면 숫자가 올라가는 기능
App.jsx
import "./App.css";
import Bulb from "./components/Bulb";
import Counter from "./components/Counter";
function App() {
return (
<>
<Bulb />
<Counter />
</>
);
}
export default App;
- 두 개의 컴포넌트를 자식 컴포넌트로 가지고 있는 부모 컴포넌트
- Counter 버튼을 클릭해도 Bulb의 영향이 가지 않고, Bulb 버튼을 클릭해도 Counter의 영향이 없다.
State로 사용자 입력 관리하기
- 간단히 회원가입 폼을 만들기
Register.jsx
import { useState } from "react";
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개
const Register = () => {
const [name, setName] = useState("이름");
const [birth, setBirth] = useState("");
const [country, setCountry] = useState("");
const [bio, setBio] = useState("");
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeBirth = (e) => {
setBirth(e.target.value);
};
const onChangeCountry = (e) => {
setCountry(e.target.value);
};
const onChangeBio = (e) => {
setBio(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} placeholder={"이름"} />
</div>
<div>
<input value={birth} type="date" onChange={onChangeBirth} />
</div>
<div>
<select value={country} onChange={onChangeCountry}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="cn">중국</option>
</select>
</div>
<div>
<textarea value={bio} onChange={onChangeBio} />
{bio}
</div>
</div>
);
};
export default Register;
- 하나의 객체값으로 통합하고 스프레드 연산자를 사용해 중복코드 제거하기
import { useState } from "react";
const Register = () => {
const [input, setInput] = useState({
name: "",
birth: "",
country: "",
bio: "",
});
console.log(input);
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={"이름"}
/>
</div>
<div>
<input value={input.birth} type="date" onChange={onChangeBirth} />
</div>
<div>
<select value={input.country} onChange={onChangeCountry}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="cn">중국</option>
</select>
</div>
<div>
<textarea value={input.bio} onChange={onChangeBio} />
</div>
</div>
);
};
export default Register;
- 중복되는 이벤트 핸들러도 통합 이벤트 핸들러로 만들기
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={"이름"}
/>
</div>
<div>
<input
name="birth"
value={input.birth}
type="date"
onChange={onChange}
/>
</div>
<div>
<select name="country" value={input.country} onChange={onChange}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="cn">중국</option>
</select>
</div>
<div>
<textarea name="bio" value={input.bio} onChange={onChange} />
</div>
</div>
);
};
export default Register;
- [e.target.name]: e.target.value 이 부분이 중요한데, key : value로 작동한다.
- 자바 스크립트의 객체 프로퍼티(객체 속성) 문법을 이용한 것으로, 대괄호 안에 어떤 변수명을 넣으면 프로퍼티의 key로써 설정이 된다는 점!
출처 : 한입 크기로 잘라먹는 리액트
'Language > React.js' 카테고리의 다른 글
[React] 라이프 사이클 (1) | 2024.10.17 |
---|---|
[React] useRef와 Custom Hooks (0) | 2024.10.17 |
[React] Props와 EventHandling 기초 (0) | 2024.10.16 |
[React] React Component 와 JSX문법 (0) | 2024.10.11 |
[React] 리액트 App 설치하고 실행하기 (0) | 2024.10.11 |