아래는 input으로 제목과 내용을 입력받아 Todolist에 저장하는 코드이다.
Input.js
import React from "react";
const Input = () =>{
return (
<section>
<form className="add-form" onSubmit={onSubmitHandler}>
<div className="input-group">
<label className="form-label">제목</label>
<input
required
className="add-input"
type="text"
name="title"
value={todo.title}
onChange={titleChange}
/>
<label className="form-label">내용</label>
<input
required
className="add-input"
type="text"
name="contents"
value={todo.contents}
onChange={contentsHandler}
/>
</div>
<button className="add_btn">추가하기</button>
</form>
</section>
);
};
export default Input;
Input 2개와 버튼 1개가 있을 때, 각 Input마다 state를 생성하고 각 state를 업데이트를 작성하였다.
function Input({ setTodos, todos }) {
//input state
const [title, setTitle] = useState("");
const [contents, setContents] = useState("");
//각 state 업데이트할 함수
const titleChange = (event) => {
setTitle(event.target.value);
};
const contentsChange = (event) => {
setContents(event.target.value);
};
const onSubmitHandler = (event) => {
event.preventDefault();
const newTodo = {
title,
contents,
isDone: false,
id: uuidv4(),
};
setTodos([...todos, newTodo]); //불변성 유지
setTtile("");
setContents("");
};
각 input에 따른 useState를 작성하고 각 State를 업데이트 해 줄 함수도 작성하면 코드가 길어져 비효율적이다.
Input의 정보를 객체형태로 useState 하나에 작성하고 하나의 함수를 이용하여 코드를 간결하게 작성해보자!
title과 contents을 todo라는 객체로 useState 하나에 작성한 코드는 다음과 같다.
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
function Input({ setTodos, todos }) {
const initState = {
id: 0,
title: "",
contents: "",
isDone: false,
};
const [todo, setTodo] = useState(initState);
const onChangeHandler = (event) => {
//value = title, neme = contents
const { value, name } = event.target;
//얕은복사로기존값복사하고 새로추가된 값들 대입
setTodo({ ...todo, [name]: value, id: uuidv4() });
};
const onSubmitHandler = (event) => {
event.preventDefault();
setTodos([...todos, todo]); //불변성 유지
//input창 비우기
setTodo(initState);
};
return (
<section>
<form className="add-form" onSubmit={onSubmitHandler}>
<div className="input-group">
<label className="form-label">제목</label>
<input
required
className="add-input"
type="text"
name="title"
value={todo.title}
onChange={onChangeHandler}
/>
<label className="form-label">내용</label>
<input
required
className="add-input"
type="text"
name="contents"
value={todo.contents}
onChange={onChangeHandler}
/>
</div>
<button className="add_btn">추가하기</button>
</form>
</section>
);
}
export default Input;
아래 그림은 onChangeHandler안에있는 event.target을 console에 찍은 값이다.
value에 우리가 입력한 값이 저장되고, name으로 title과 contents가 구분됨을 알 수 있다
따라서, const { value, name } = event.targe; 은 비구조화 할당으로 값을 추출한 것이다.
setTodo({ ...todo, [name]: value, id: uuidv4() });
- ...todo : 불변성을 유지하기위해, spread문법으로 todo 객체를 펼쳐 객체를 복해주었다.
- [name] : value에서 []를 사용한 이유는 객체의 key 값을 동적으로 할당하기 위해서이다.
[name]은 name의 변수, 즉 title과 contents를 불러온다.
'리액트' 카테고리의 다른 글
CryptoJS를 활용한 RefreshToken 암호화 및 복호화 - 안전한 로그인 토큰 관리 방법 (0) | 2023.05.24 |
---|---|
[React] 옵셔널 체이닝(Optional Chaining) (0) | 2023.04.28 |
[React/Warning]Each child in a list should have a unique " key" prop. (0) | 2023.04.18 |
[React] Props란, Props Children (0) | 2023.04.18 |
[React] CRA란? CRA로 리액프 트로젝트 생성하기 (1) | 2023.04.18 |
댓글