Intro
- 간단한 ToDo-list 어플
- 배열 State에 새로운 값 추가하기
- 배열 State값을 component로 render하기
State 연습을 위해 할 일을 추가할 수 있는 간단한 투두리스트 어플을 만들어보려고 한다.
State의 기본적인 내용은 이전 포스팅에 정리해놓았다.
배열 State
할 일(toDo)를 여러개 저장하기 위해 배열 State인 toDos를 정의한다.
const [toDo, setToDo] = useState("");
const [toDos, setToDos] = useState([]); // 배열 State
그리고 이 배열 State에 값을 추가(push)하고 싶다면?
일반적인 자바스크립트에서라면 toDos.push를 사용했겠지만, 리액트에서는 state 값을 직접적으로 수정해줄 수 없다.
절대 toDo ="" 를 사용하지 않는 것처럼 말이다. 대신에 우리는 함수를 사용하고 그 함수가 toDo를 수정하는 역할을 할것이다. 바로 setTodos 함수이다.
이제 함수에서 input을 통해 작성한 todo를 array에 넣기 전, 이미 있는 배열에 새로운 element를 추가하기위한 코드를 작성하기 전 문법을 알아보자면 아래와 같다.
const food = [1,2,3,4]
// food array에 새롭게 6을 더해서 새로운 array를 만들기
[6, food] // [6,Array(4)] -> 6과 그 안에 또 다른 array 생김
[6, ...food] // [6,1,2,3,4] -> ...으로 food의 element가져옴
우리는 이 문법을 참고해서 setToDos 함수를 아래와 같이 작성할 수 있다. 함수를 전달해 state 값을 변경하는 방식을 사용했다.
setToDos((currentArray) => [toDo, ...currentArray]);
그리고 제목에 추가된 할 일의 개수를 띄우기 위해 toDos.length를 추가한다. 이 때, JSX에서 자바스크립트를 사용하려면 중괄호를 넣어줘야한다는 것을 잊지 말자. 만약 useState 함수 안에 인자를 비워둔다면 에러가
<h1>My To Dos ({toDos.length})</h1>
맨 처음에는 비어있는 userState() 함수 안 인자를 비어있는 array로 두었기 때문에 0으로 뜰텐데, 인자를 주지 않는다면 컴포넌트의 시작인 todos가 undefinded이기 때문에 에러가 난다. 그러므로 적어도 빈 array로 기본값을 지정해주도록 하자.
map()
array로부터 동일한 component에 있는 많은 것들을 render 하고 싶을 때, array.map() 함수를 사용할 수 있다. (참고로 map()은 자바스크립트 문법이다.) map()은 인자로 함수를 받는데, array의 모든 item에 대해 실행되고 함수로부터 return한 값이 새로운 array에 들어가도록 한다.
['one', 'two', 'three'].map(() => ":)")
// [':)', ':)', ':)']
['one', 'two', 'three'].map((item) => item.toUpperCase())
// ['ONE', 'TWO', ;THREE']
여기서 포인트는, map은 함수의 첫번째 인자로 현재의 item을 가져올 수 있다는 점이다. 우리는 map을 이용해 컴포넌트를 return 시키려고 한다. ul 태그 안의 li로 출력되도록 했다.
<ul>
{toDos.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
같은 컴포넌트의 list를 render할 때, react는 element에 key라는 prop을 넣어줘야 한다. key는 React.js에서만 map 안에서 컴포넌트들을 render할 때 사용한다. 여기서는 index를 넣어주도록 한다.
완성된 앱의 전체 코드와 작동은 다음과 같다.
import { useEffect, useState } from "react";
function App() {
const [toDo, setToDo] = useState("");
const [toDos, setToDos] = useState([]);
const onChange = (event) => setToDo(event.target.value);
const onSubmit = (event) => {
event.preventDefault();
if (toDo === "") {
return;
}
setToDos((currentArray) => [toDo, ...currentArray]);
setToDo("");
};
console.log("toDos");
return (
<div>
<h1>My To Dos ({toDos.length})</h1>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={toDo}
type="text"
placeholder="Write your to do..."
/>
<button>Add To Do</button>
</form>
<hr />
<ul>
{toDos.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default App;
'WEB > React' 카테고리의 다른 글
[React] React Router 사용하기 (0) | 2022.02.03 |
---|---|
[React] API 사용하기 (0) | 2022.02.02 |
[React] Effects (useEffect, clean-up) (0) | 2022.01.29 |
[React] Props (Memo, Props Types) (0) | 2022.01.28 |
[React] State (0) | 2022.01.28 |