
리액트 기초 익히기
npm (Node Package Manager)은 Node.js의 패키지 관리자로, JavaScript 라이브러리와 응용 프로그램을 공유하고 관리하는 플랫폼이에요. npm을 통해 필요한 라이브러리를 쉽게 설치하고 관리할 수 있어요.
package 의 의존성을 관리 + 버전 정보 기록
npx는 node.js를 위한 패키지 실행도구
node를 설치하면 npm과 함께 설치
npx를 사용하면 컴퓨터에 설치하지 않은 npm 패키지를 실행할 수 있고, 프로젝트에 설치된 패키지도 쉽게 실행할 수 있다
function Greeting() {
return <div>Hello World</div>
}
<Greeting />
React 프로젝트 생성하기
npx create-react-app 원하는프로젝트명

node_modules: npm으로 설치한 패키지들이 저장되어 있는 디렉터리에요.public: 우리 웹서비스의 루트 경로(/)에서 바로 접근 가능한 에셋들을 담아 두는 디렉터리에요.src: 우리 웹서비스의 주요 소스 코드들을 저장하고 관리하는 디렉터리에요.App.js: 프로젝트의 루트 컴포넌트에요.App.css: 루트 컴포넌트에서 사용할 스타일들을 담아 둔 스타일시트 파일이에요.index.css: 프로젝트 전반에 걸쳐 사용할 스타일들을 담아 둔 스타일시트 파일이에요.index.js: 루트 컴포넌트를 HTML document에 연결시켜주는 코드가 들어 있는 JS 파일이에요package.json: 프로젝트의 주요 정보들을(이름, 설치된 패키지, 스크립트 등) 담고 있는 파일이에요.package-lock.json: package.json을 통해 설치된 패키지들의 상세 정보들을 담고 있는 파일이에요props(데이터 흐름 만들기)
부모 컴포넌트로부터 자식 컴포넌트에 전달하는 데이터를 Props
자식 컴포넌트 입장에서 Props는 읽기 전용으로, 수정불가
props를 잘 사용하면 컴포넌트의 재사용성과 유연성이 크게 증가해요.
부모가 전달해 주는 props 값이 바뀌면 자식 컴포넌트는 리렌더링을 해요.
function Greeting(props) {
return <h1>안녕하세요, {props.name}님!</h1>;
}
function App() {
const someName = "철수"
return (
<div>
<Greeting name="지수" />
<Greeting name={someName} />
</div>
);
}
<Display>ㅎㅇ</Display>
숫자라던가 텍스트가 아닌 다른값을 props 로 넘길때에는
<Display number={5} />
함수는 handleClick 이렇게 동사형태로 명칭짓기
input 은 onChange
button 은 onClick
둘다 안에 이벤트 객체가 들어있고 반환해.
State
컴포넌트의 기억공간( 현재 입력되고 있는 값 or 이미지 등등 기억을 보관해야하기때문)
State가 바뀌면 컴포넌트는 리렌더링을 한다.
함수가 재실행된다(= 리렌더링 된다) => 화면 다시 렌더링
함수는 재실행되지만 상태값은 초기화가 되지않고 어딘가에 계속 기억이 되고 있다.
카운터 만들기
const [count, setCount] = useState();
구조 분해로 바로 받기.
그냥 근데 count 를 바꿀 수 없어. => const 기 때문.
setCount(count +1)로 바꿔
const [count, setCount] = useState(0);
const handleClickButton = () => {
setCount(count + 1);
setCount((prevCount) => prevCount + 1);
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
const [gap, setGap] = useState(1);
console.log();
const handleClickMinus = () => {
setCount(count - gap);
};
const handleClickPlus = () => {
setCount(count + gap);
};
return (
<div>
<h2>카운터</h2>
<div>현재 숫자: {count}</div>
<input
type="number"
value={String(gap)}
onChange={(e) => {
setGap(Number(e.target.value));
}}
/>
<div>
<button onClick={handleClickMinus}>-</button>
<button onClick={handleClickPlus}>+</button>
</div>
</div>
);
}
export default Counter;
색상 선택기 만들기
<button onClick={handleClickColor("red")}>빨강</button>
<button onClick={handleClickColor("orange")}>주황</button>
<button onClick={() => handleClickColor("yellow")}>노랑</button> x
<button onClick={() => handleClickColor("green")}>초록</button> x
<button onClick={() => handleClickColor("indigo")}>군청</button>x
const handleClickColor = (color) => {
return () => setSelectedColor(color);
};
onClick 에는 함수가 들어가야해. 근데 화살표 함수 없이 그냥 쓰면 바로 handleClickCOlor 를 호출 하니까 안돼.
import React, { useState } from "react";
function ColorSelector() {
const [selectedColor, setSelectedColor] = useState("black");
const handleClickColor = (color) => {
setSelectedColor(color);
};
return (
<div>
<h2>색상선택기</h2>
<div
style={{
backgroundColor: selectedColor,
width: 100,
height: 100,
margin: "0 auto",
}}
></div>
<div>
{/* 바로호출되니까 이를 방지하기 위해 화살표 함수로 감싸 */}
<button onClick={() => handleClickColor("red")}>빨강</button>
<button onClick={() => handleClickColor("orange")}>주황</button>
<button onClick={() => handleClickColor("yellow")}>노랑</button>
<button onClick={() => handleClickColor("green")}>초록</button>
<button onClick={() => handleClickColor("indigo")}>군청</button>
<button onClick={() => handleClickColor("purple")}>보라</button>
</div>
</div>
);
}
export default ColorSelector;
회원가입 양식 만들기
html에서 Form 태그는 기본적으로 폼이 제출되면 페이지가 새로고침돼. (post 방식으로 보내기 때문에)
하지만 우리는 그런방식으로 하지 않아서 이를 막아야해.
import React, { useState } from "react";
function SignUpForm() {
const [id, setId] = useState("");
const [password, setPassword] = useState("");
const [password2, setPassword2] = useState("");
const [nickname, setNickname] = useState("");
const [gender, setGender] = useState("");
console.log(gender);
const handleClickSignUp = () => {
if (password !== password2) return alert("비밀번호 일치 X");
const data = {
id,
password,
nickname,
gender,
};
console.log(data);
};
return (
<div>
<h2>회원가입 양식</h2>
<form
style={{
display: "flex",
flexDirection: "column",
maxWidth: 200,
margin: "0 auto",
rowGap: 12,
}}
// 제출되면 기본동작을 막겠다(새로고침되는)
onSubmit={(e) => e.preventDefault()}
>
<input
type="text"
placeholder="ID 입력해주세요"
value={id}
onChange={(e) => setId(e.target.value)}
/>
<input
type="password"
placeholder="PW 입력해"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<input
type="password"
placeholder="PW 한번더 입력해"
value={password2}
onChange={(e) => setPassword2(e.target.value)}
/>
<input
type="text"
placeholder="닉네임 입력해"
value={nickname}
onChange={(e) => setNickname(e.target.value)}
/>
<div style={{ display: "flex" }}>
<div>
<input
id="gender-female"
type="radio"
name="gender"
value="female"
checked={gender === "여자"}
onChange={(e) => e.target.checked === true && setGender("여자")}
/>
<label htmlFor="gender-female">여자</label>
</div>
<div>
<input
id="gender-male"
type="radio"
name="gender"
value="male"
checked={gender === "남자"}
onChange={(e) => e.target.checked === true && setGender("남자")}
/>
<label htmlFor="gender-male">남자</label>
</div>
</div>
<button onClick={handleClickSignUp}> 가입하기</button>
</form>
</div>
);
}
export default SignUpForm;
https://instructor-young.notion.site/f5de06b7bc824f03a3bc94c386f6c393