요르딩딩
섹션6. React.js 입문 본문
728x90
반응형
섹션5. React.js 개론
// 리액트앱 생성.
npm create vite@latest
// package.json의 dependencies들 설치.
npm i
// 실행
npm run dev
// eslint 확장 프로그램 설치
// 작성한 코드를 정적으로 검토하여 미리 오류로 띄워줌
.eslinttrc.cjs > "no-unused-vars" : "off", (미사용변수 오류처리 안되도록.)
.eslinttrc.cjs > "react[prop-types" : "off" (안전하게 사용할수 있도록 해주지만 실습시 불필요)
5.2) React 컴포넌트
// App.jsx
App Component : HTML 태그를 반환하는 함수 (함수 컴포넌트)
// 컴포넌트 생성 방법
// 첫글자는 대문자!!!
1. function Header(){}
2. const Header = () => {}
// App(부모 컴포넌트) -> Header(자식 컴포넌트), Main, Footer
// App(루트 컴포넌트)
// 컴포넌트 가져오기/내보내기
import Header from "./components/Header";
export default Header;
5.3) JSX로 UI 표현하기



import "./Main.css";
// JSX 주의 사항
// 1. 중괄호 내부에는 자바스크립트 표현식만 넣을 수 있다
// 2. 숫자, 문자열, 배열 값만 렌더링 된다
// 3. 모든 태그는 닫혀있어야 한다
// 4. 최상위 태그는 반드시 하나여야만 한다. <></> 빈태그도 가능 -> 흩뿌려져있는것으로 간주
const Main = () => {
const user = {
name: "이정환",
isLogin: true,
};
if (user.isLogin) {
return <div className="logout">로그아웃</div>; // logout은 CSS파일
} else {
return <div>로그인</div>;
}
// return (
// <>
// {user.isLogin ? (
// <div>로그아웃</div>
// ) : (
// <div>로그인</div>
// )}
// </>
// );
};
export default Main;
5.4) Props로 데이터 전달하기

// Props : 부모 -> 자식에게 값을 전달할 수 있음!!!
import "./App.css";
import Header from "./components/Header";
import Main from "./components/Main";
import Footer from "./components/Footer";
import Button from "./components/Button";
function App() {
const buttonProps = { // 객체!!!
text: "메일",
color: "red",
a: 1,
b: 2,
c: 3,
};
return (
<>
<Button {...buttonProps} /> // 스프레드 연산자!!! (값 그대로 가져오기)
<Button text={"카페"} />
<Button text={"블로그"}>
<Header /> // children으로 넘어감!!!
</Button>
</>
);
}
export default App;
// 구조분해할당 (undefined에러 주의 : 기본값 설정)
// children : 자식 컴포넌트의 값 넘어옴!!!
const Button = ({ text, color="black", children }) => {
return (
<button style={{ color: color }}>
{text} - {color.toUpperCase()}
{children}
</button>
);
};
export default Button;
5.5) 이벤트 처리하기


const Button = ({ text, color, children }) => {
// 이벤트 객체
const onClickButton = (e) => { // e는 이벤트 객체 : 통합된 규격의 이벤트 객체
console.log(e);
console.log(text);
};
return (
<button
onClick={onClickButton}
// onMouseEnter={onClickButton} // 마우스 오버시 동작
style={{ color: color }}
>
{text} - {color.toUpperCase()}
{children}
</button>
);
};
Button.defaultProps = {
color: "black",
};
export default Button;
5.6) State로 상태관리하기

import "./App.css";
import { useState } from "react";
// state를 사용하는 이유 : 일반변수는 변경이 생겨도 리랜더링 되지 않기때문!!!
function App() {
const [count, setCount] = useState(0); // 구조분해할당방식
const [light, setLight] = useState("OFF");
return ( // 리랜더링됨.
<>
<div>
<h1>{light}</h1>
<button
onClick={() => {
setLight(light === "ON" ? "OFF" : "ON");
// setState(state +1); // 1씩 증가
}}
>
{light === "ON" ? "끄기" : "켜기"}
</button>
</div>
<div>
<h1>{count}</h1>
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
</>
);
}
export default App;
5.7) State와 Props
- [리랜더링 되는 상황]
1. 자신의 state가 변경되었을때
2. 자신의 props가 변경되었을때
3. 부모 컴포넌트가 리랜더링되었을때
import "./App.css";
import Bulb from "./components/Bulb";
import Counter from "./components/Counter";
function App() {
return (
<>
<Bulb />
<Counter />
</>
);
}
export default App;
import { useState } from "react";
const Bulb = () => { // 부모로 부터받은 Props가 변경되어도 리랜더링된다!!!
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;
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;
5.8) State로 사용자 입력 관리하기 1

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} // input칸에 보여줌!!!
onChange={onChangeName} // 값이 입력될때마다 동작!!!
placeholder={"이름"} // 입력되기전에 보여주는 임시 문구 (회색)!!!
/>
</div>
<div>
<input
value={birth}
onChange={onChangeBirth}
type="date"
/>
</div>
<div>
<select value={country} onChange={onChangeCountry}>
<option value=""></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
{country}
</div>
<div>
<textarea value={bio} onChange={onChangeBio} />
</div>
</div>
);
};
export default Register;
5.9) State로 사용자 입력 관리하기
import { useState } from "react";
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개
const Register = () => {
const [input, setInput] = useState({
name: "",
gender: "",
bio: "",
});
const onChange = (e) => {
console.log(e.target.name + " : " + e.target.value);
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}
onChange={onChange}
type="date"
/>
</div>
<div>
<select
name="country"
value={input.country}
onChange={onChange}
>
<option value=""></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
</div>
<div>
<textarea
name="bio"
value={input.bio}
onChange={onChange}
/>
</div>
</div>
);
};
export default Register;
5.10) useRef로 컴포넌트의 변수 생성하기
- useRef : 해당 컴포넌트가 리랜더링 되더라도 특수한 경우로 값이 초기화 되지 않음.
- 일반변수 : 해당 컴포넌트가 리랜더링되면, 초기화도 같이 일어나 값이 유지될 수 없음.
-> 컴포넌트를 두번 호출한것은 함수만 호출한것으로, 전역변수로 선언되어있는 변수는
2개의 컴포넌트에서 같이 사용하게 된다. (의도와 다름)



import { useState, useRef } from "react";
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개
const Register = () => {
const [input, setInput] = useState({
name: "",
birth: "",
country: "",
bio: "",
});
const countRef = useRef(0);
const inputRef = useRef(); // 값이 변경되어도 리랜더링되지 않음!!!
const onChange = (e) => {
// countRef.current++; // 값이 변경되어도 리랜더링되지 않음!!!
count++;
console.log(count);
setInput({
...input,
[e.target.name]: e.target.value,
});
};
const onSubmit = () => {
if (input.name === "") {
inputRef.current.focus(); // 이름을 입력하는 DOM 요소(HTML태그?) 포커스!!!
}
};
return (
<div>
<div>
<input
ref={inputRef} // REF값 저장!!!
name="name"
value={input.name}
onChange={onChange}
placeholder={"이름"}
/>
</div>
<div>
<input
name="birth"
value={input.birth}
onChange={onChange}
type="date"
/>
</div>
<div>
<select
name="country"
value={input.country}
onChange={onChange}
>
<option value=""></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
</div>
<div>
<textarea
name="bio"
value={input.bio}
onChange={onChange}
/>
</div>
<button onClick={onSubmit}>제출</button>
</div>
);
};
export default Register;
5.11) React Hooks


import { useState } from "react";
function useInput() { // 커스텀 Hooks!!!
const [input, setInput] = useState("");
const onChange = (e) => {
setInput(e.target.value);
};
return [input, onChange]; // 구조분해할당!!!
}
export default useInput;
import useInput from "./../hooks/useInput";
// 3가지 hook 관련된 팁
// 1. 함수 컴포넌트, 커스텀 훅 내부에서만 호출 가능
// 2. 조건부로 호출될 수는 없다 (호출순서가 엉망이 될 수 있음!!!)
// 3. 나만의 훅(Custom Hook) 직접 만들 수 있다.
const HookExam = () => {
const [input, onChange] = useInput();
const [input2, onChange2] = useInput();
return (
<div>
<input value={input} onChange={onChange} />
<input value={input2} onChange={onChange2} />
</div>
);
};
export default HookExam;
728x90
반응형
'[강의] > [한 입 크기로 잘라 먹는 리액트(React.js)]' 카테고리의 다른 글
섹션8. 라이프사이 (0) | 2025.04.02 |
---|---|
섹션7. 프로젝트1. 카운터 (0) | 2025.04.02 |
섹션5. React.js 개론 (0) | 2025.03.28 |
섹션4. Node.js 기초 (0) | 2025.03.26 |
섹션3. JavaScript 심화 (0) | 2025.03.21 |