이번 세션에서는 미니프로젝트를 진행했다.
사용자에게 이름과 나이를 입력받아 밑에 출력하는 것을 만들었고,
이용자 이름과 나이가 비어있거나 나이가 1살보다 어리면 모달로 창을 띄우는 것까지 했다.
이번 강의는 그동안 진행했던 리액트 프로젝트때 사용했던 로직과 비슷했다.
그래서 이번 포스팅은 새롭게 배운 점 및 기억해둘 것 위주로 정리했다.
children
//Card.js
const Card = props => {
return (
<div className={`${classes.card} ${props.className}`}>{props.children}</div>
);
};
export default Card;
//ErrorModal.js
<Card className={classes.modal}>
<hearder>
<h2 className={classes.header}>{props.title}</h2>
</hearder>
<div className={classes.content}>
<p>{props.message}</p>
</div>
<footer className={classes.actions}>
<Button onClick={props.onConfirm}>Okay</Button>
</footer>
</Card>
form
label
과 input
을 htmlFor
와 id
를 이용해서 연결해주자!<form onSubmit={addUserHandler}>
{/* className대신 label의 쓰임새를 정해줄때는 htmlFor사용 */}
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
value={enteredUsername}
onChange={usernameChangeHandler}
/>
<label htmlFor="age">Age(numbers)</label>
<input
id="age"
type="number"
value={enteredUserAge}
onChange={ageChangeHandler}
/>
<Button type="submit">Add User</Button>
</form>
trim
파일명.module.css
이름의 파일을 생성한다.className
을 정해서 작성한다.className
을 css에서 작성한 이름으로 넣어준다.
//UserList.module.css
.users {
margin: 2rem auto;
width: 90%;
max-width: 40rem;
}
.users ul {
list-style: none;
padding: 1rem;
}
.users li {
border: 1px solid #ccc;
margin: 0.5rem 0;
padding: 0.5rem;
}
//UserList.js
import React from "react";
import Card from "../UI/Card";
/* classes라는 이름으로 CSS파일을 임포트해온다. */
import classes from "./UsersList.module.css";
const UserList = props => {
return (
/*클래스 이름을 적용해준다.*/
<Card className={classes.users}>
<ul>
{props.users.map(user => (
<li key={user.id}>
{user.name} ({user.age} years old)
</li>
))}
</ul>
</Card>
);
};
export default UserList;
/*error에 따라 모달창을 표시하는 컴포넌트*/
//AddUser.js
import React, { useState } from "react";
import Button from "../UI/Button";
import Card from "../UI/Card";
import ErrorModal from "../UI/ErrorModal";
import classes from "./AddUser.module.css";
const AddUser = props => {
const [enteredUsername, setEnteredUsername] = useState("");
const [enteredUserAge, setEnteredUserAge] = useState("");
//모달을 트리거 할 수 있는 변수
const [error, setError] = useState();
const addUserHandler = event => {
event.preventDefault();
//조건에 안 맞으면 에러를 설정
if (
enteredUsername.trim().length === 0 ||
enteredUserAge.trim().length === 0
) {
setError({
title: "Invaild input",
message: "Please enter a vaild name and age (non-empty values).",
});
return;
}
if (+enteredUserAge < 1) {
setError({
title: "Invaild enter",
message: "Please enter a vaild age.",
});
return;
}
props.onAddUser(enteredUsername, enteredUserAge);
setEnteredUsername();
setEnteredUserAge();
};
const usernameChangeHandler = event => {
setEnteredUsername(event.target.value);
};
const ageChangeHandler = event => {
setEnteredUserAge(event.target.value);
};
//에러창을 끄면 error를 Null로 만들어서 에러 없애기
const errorHandler = () => {
setError(null);
};
return (
<>
{/*error가 null이 아니라면 모달창이 뜸*/}
{error && (
<ErrorModal
title={error.title}
message={error.message}
onConfirm={errorHandler}
/>
)}
<Card className={classes.input}>
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
value={enteredUsername}
onChange={usernameChangeHandler}
/>
<label htmlFor="age">Age(numbers)</label>
<input
id="age"
type="number"
value={enteredUserAge}
onChange={ageChangeHandler}
/>
<Button type="submit">Add User</Button>
</form>
</Card>
</>
);
};
export default AddUser;
/*에러를 표시하는 Error Modal*/
import React from "react";
import Card from "./Card";
import Button from "./Button";
import classes from "./ErrorModal.module.css";
const ErrorModal = props => {
return (
<>
{/* 에러가 뜨면 모달창 뒤로 배경을 어둡게 함, 클릭시 에러가 사라짐 */}
<div className={classes.backdrop} onClick={props.onConfirm}></div>
<Card className={classes.modal}>
<hearder>
<h2 className={classes.header}>{props.title}</h2>
</hearder>
<div className={classes.content}>
<p>{props.message}</p>
</div>
{/*okay버튼을 누르면 에러가 사라짐*/}
<footer className={classes.actions}>
<Button onClick={props.onConfirm}>Okay</Button>
</footer>
</Card>
</>
);
};
export default ErrorModal;
/*ErrorModal.module.css*/
.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 10;
background: rgba(0, 0, 0, 0.75);
}
...
import React, { useState } from "react";
import AddUser from "./components/Users/AddUser";
import UserList from "./components/Users/UsersList";
function App() {
const [usersList, setUsersList] = useState([]);
const addUserHandler = (uName, uAge) => {
setUsersList(prevUserList => {
return [
...prevUserList,
{ name: uName, age: uAge, id: Math.random().toString() },
];
});
};
return (
<div>
<AddUser onAddUser={addUserHandler} />
<UserList users={usersList} />
</div>
);
}
export default App;