실습)
1. Counter 만들기
+버튼과 -버튼을 누를 때 숫자가 카운트된다
import React, { useState } from "react";
function App() {
const [number, setNumber] = useState(0);
return (
<div>
{number}
<button onClick={() => {setNumber(number + 1);}}> + </button>
<button onClick={() => {setNumber(number - 1);}}> - </button>
</div>
);
}
export default App;
2. js css파일 분리하기
예제 1)

import React from "react";
import "./App.css";
const App = () => {
const style = {
padding: "100px",
display: "flex",
gap: "12px",
};
const squareStyle = {
width: "100px",
height: "100px",
border: "1px solid green", // 1px의 초록색 실선 테두리
borderRadius: "10px",
display: "flex",
alignItems: "center", // 중앙정렬
justifyContent: "center", // 행의 위치
};
return (
<div style={style}>
<div style={squareStyle}>감자</div>
<div style={squareStyle}>고구마</div>
<div style={squareStyle}>오이</div>
<div style={squareStyle}>가지</div>
<div style={squareStyle}>옥수수</div>
</div>
);
};
export default App;
=> css파일과 js파일 분리하면
// App.css
.app-style {
padding: 100px;
display: flex;
gap: 12px;
}
.square-style {
width: 100px;
height: 100px;
border: 1px solid green;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
}
// App.js
import React from "react";
import "./App.css";
const App = () => {
return (
<div className="app-style">
<div className="square-style">감자</div>
<div className="square-style">고구마</div>
<div className="square-style">오이</div>
<div className="square-style">가지</div>
<div className="square-style">옥수수</div>
</div>
);
};
export default App;
* jsx문법을 사용하기 때문에 js파일은 웬만하면 jsx로 수정하기!! ex) App.js -> App.jsx
같은 코드의 중복을 막기 위해 map과 filter 적용↓
import React from "react";
import "./App.css";
const App = () => {
const vegetables = ["감자", "고구마", "오이", "가지", "옥수수"];
return (
<div className="app-style">
{/* jsx 부분에서 js코드(map)을 작성할 것이기 때문에 {}를 사용 */}
{vegetables.map((vegetableName) => {
return (
<div className="square-style" key={vegetableName}>
{vegetableName}
</div>
);
})}
</div>
);
};
export default App;
예제 2)

import React from "react";
import "./App.css"; // 🔥 반드시 App.css 파일을 import 해줘야
function User(props) {
return (
<div className="square-style">
{props.user.age}살 - {props.user.name}
</div>
);
}
const App = () => {
const users = [
{ id: 1, age: 30, name: "송중기" },
{ id: 2, age: 24, name: "송강" },
{ id: 3, age: 21, name: "김유정" },
{ id: 4, age: 29, name: "구교환" },
];
return (
<div className="app-style">
{users.map((user) => {
return <User user={user} key={user.id}></User>;
})}
{/* 각각의 user에 대한 props를 넘겨줌 */}
</div>
);
};
export default App;
실습 - 삭제&취소 버튼)
import React, { useState } from "react";
import "./App.css"; // 🔥 반드시 App.css 파일을 import 해줘야
function CustomButton(props) {
const { color, onClick, children } = props;
if (color) {
return (
<button
style={{ backgroundColor: color, color: "white" }}
onClick={onClick}
>
{children}
</button>
);
}
// 만약 받아온 props에 color가 있다면 컬러버튼을 return할 것!
return <button onClick={onClick}>{children}</button>;
}
function User(props) {
return (
<div className="square-style">
{props.user.age}살 - {props.user.name}
<CustomButton
color="red"
onClick={() => props.handleDelete(props.user.id)}
>
삭제하기
</CustomButton>
</div>
);
}
const App = () => {
const [users, setUsers] = useState([
// 추가 및 삭제를 하기 위해 useState사용
{ id: 1, age: 30, name: "송중기" },
{ id: 2, age: 24, name: "송강" },
{ id: 3, age: 21, name: "김유정" },
{ id: 4, age: 29, name: "구교환" },
]);
const [name, setName] = useState("");
const [age, setAge] = useState("");
const addUserHandler = () => {
const newUser = { id: users.length + 1, age: age, name: name };
//user(배열)의 길이를 추가한다는 뜻!
setUsers([...users, newUser]); // 기존 users 배열에 추가해주는 코드
// 배열을 만들고, 스프레드문법을 통해 기존에 있던 users 배열에 추가한다는 의미
};
const deleteUserHandler = (id) => {
// 삭제버튼 // 삭제할 id 받기
const newUserList = users.filter((user) => user.id !== id);
// user의 id가 설정한 id와 같지 않으면, 그것만 filter해서 새로운 유저리스트를 만듦
setUsers(newUserList);
// const newUserList = ;
// setUsers(users.filter((user) => user.id !== id));
// 일회성 변수가 싫다면 위의 두 줄을 사용해도 괜찮음
};
return (
<div>
<div className="app-style">
{users.map((user) => {
return (
<User
handleDelete={deleteUserHandler}
user={user}
key={user.id}
// 리액트에서 컴포넌트 배열을 렌더링할 때,
// 각각의 원소에서 변동이 있는지 알아내려고 사용하는 것이기 때문에 key값이 필요
// 만약 key가 없다면 리액트는 가상DOM을 비교하는 과정에서 배열을 순차적으로
// 비교하면서 변화를 감지하려고 할 것
// key로 어떤 변화가 일어났는지 더 빠르게 알아낼 수 있음!(리액트 성능 최적화)
// props처럼 생겼지만 props로 설정하지 않아도 key는 넣을 수 있음
></User>
);
})}
{/* handleDelete={deleteUserHandler} -> user에 Props로 delete 함수를 넣음*/}
{/* 각각의 user에 대한 props를 넘겨줌 */}
</div>
<input
value={name}
placeholder="이름을 입력해주세요"
// 인풋 이벤트로 들어온 입력 값을 name의 값으로 업데이트
onChange={(e) => setName(e.target.value)}
/>
<input
value={age}
placeholder="나이를 입력해주세요"
// 인풋 이벤트로 들어온 입력 값을 age의 값으로 업데이트
onChange={(e) => setAge(e.target.value)}
/>
<CustomButton color="green" onClick={addUserHandler}>
추가하기
</CustomButton>
</div>
);
};
export default App;
위의 예제에서 age가 25 이상인 user를 제외하고 렌더링↓
import React, { useState } from "react";
import "./App.css"; // 🔥 반드시 App.css 파일을 import 해줘야
function CustomButton(props) {
const { color, onClick, children } = props;
if (color) {
return (
<button
style={{ backgroundColor: color, color: "white" }}
onClick={onClick}
>
{children}
</button>
);
}
return <button onClick={onClick}>{children}</button>;
}
function User(props) {
return (
<div className="square-style">
{props.user.age}살 - {props.user.name}
<CustomButton
color="red"
onClick={() => props.handleDelete(props.user.id)}
>
삭제하기
</CustomButton>
</div>
);
}
const App = () => {
const [users, setUsers] = useState([
// 추가 및 삭제를 하기 위해 useState사용
{ id: 1, age: 30, name: "송중기" },
{ id: 2, age: 24, name: "송강" },
{ id: 3, age: 21, name: "김유정" },
{ id: 4, age: 29, name: "구교환" },
]);
const [name, setName] = useState("");
const [age, setAge] = useState("");
const addUserHandler = () => {
const newUser = { id: users.length + 1, age: age, name: name };
setUsers([...users, newUser]);
};
const deleteUserHandler = (id) => {
const newUserList = users.filter((user) => user.id !== id);
setUsers(newUserList);
// const newUserList = ;
// setUsers(users.filter((user) => user.id !== id)); 로 사용해도 괜찮음
};
return (
<div>
<div className="app-style">
{users.map((user) => {
if (user.age < 25) {
return (
<User
handleDelete={deleteUserHandler}
user={user}
key={user.id}
></User>
);
} else {
return null; // 25세 이상은 출력하지 않음
}
})}
{/* handleDelete={deleteUserHandler} -> user에 Props로 delete 함수를 넣음*/}
{/* 각각의 user에 대한 props를 넘겨줌 */}
</div>
<input
value={name}
placeholder="이름을 입력해주세요"
// 인풋 이벤트로 들어온 입력 값을 name의 값으로 업데이트
onChange={(e) => setName(e.target.value)}
/>
<input
value={age}
placeholder="나이를 입력해주세요"
// 인풋 이벤트로 들어온 입력 값을 age의 값으로 업데이트
onChange={(e) => setAge(e.target.value)}
/>
<CustomButton color="green" onClick={addUserHandler}>
추가하기
</CustomButton>
</div>
);
};
export default App;
Component 분리하기)
협업하는 다른 개발자가 js파일을 보고 어떤 Component가 있을지 유추하기는 쉽지 않음
그래서, 일반적으로 계속 렌더링 해서 기능을 재사용하는 Component를 따로 분리해서 사용함!
+) 추후 정리해서 추가할 예정
후기)
과제로 todo-list 만들기가 있는데 벌써 큰일이다ㅠㅋㅋㅋㅋ
리액트 입문강의 개인과제가 벌써부터 이렇게 어렵게 느껴지는데 숙련강의 심화강의를 내가 잘 이해할 수 있을까
State Props를 알면 리액트를 얼추 알게 된 거라고 할 수 있댔는데, 개념은 이해가 되는데 코드에 적용하는 데서 막힌다
숙련강의 듣기 전에 todo-list 만들기 과제를 스스로의 힘으로 완성하고 싶지만 쉽지 않다ㅎㅎㅠㅠ
'스파르타 개발일지' 카테고리의 다른 글
| 개발일지 20221212 리액트 숙련 강의 1 (0) | 2022.12.12 |
|---|---|
| 개발일지 20221210~11 todo-list 만들기 (0) | 2022.12.11 |
| 개발일지 20221207 리액트 입문 2 (0) | 2022.12.07 |
| 개발일지 20221206 리액트 입문 강의 시작! (0) | 2022.12.06 |
| 개발일지 20221122 SPA, Firebase Setup 특강 정리 + 두 번째 프로젝트 (0) | 2022.11.22 |