whatisthis?
React JS - To Do List App(practice) 본문
To Do List App
- React JS 연습용
- create-react-app 사용
part1.
1 / 기본 틀 + 이벤트리스너 만들기
App.js
import { useState } from "react";
function App() {
const [toDo, setToDo] = useState("");
const onChange = e => {
setToDo(e.target.value);
};
const onSubmit = e => { // form 제출시
e.preventDefault();
if (toDo === "") { // toDo가 공백이면 함수를 끝내버림
return;
}
setToDo(""); // submit후 input의 value를 공백으로
};
return (
<div>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={toDo}
type="text"
placeholder="Write your to do..."
/>
<button>Add To Do</button>
</form>
</div>
);
}
export default App;
처음엔 onSubmit에서 input의 value를 어떻게 지우나 했는데
useState의 modifier함수인 setToDo함수를 한번 더 이용하면 되는구나! 싶었다.
- 함수는 무조건 재사용성 👍
toDo = "" 이렇게 비워버리면 state는 바뀌지 않는다.반드시 state는 modifier함수를 이용해야함.
state를 직접적으로 수정하면 절대 안된다.
state는 modifier함수를 통해서만 수정해야함.
2 / toDo를 받는 배열을 만들기
- 이것도 역시 useState를 이용한다.
- Default값은 대신 빈 배열 []로 지정한다.
const [toDos, setToDos] = useState([]);
- 이 또한 마찬가지로 toDos.push()를 하면 되는게 아닌가? ❌❌❌ 절대 아님.
- state를 변경하려면 절대 push로 할 수 없다.
** 배열을 합치는 방법
[1,2,3,4] 배열과 [6]배열을 합치려면?
⭕
1. concat()
arr1.concat(arr2)
2. ... (spread operator)
...arr1, ...arr2, ...arr3
❌[6, food]= [6, [1,2,3,4] ]
___
setToDos(prevArr => [toDo, ...prevArr]);
새로 받은 toDo를 맨 첫번째 요소로 두고, 이전 배열(toDos)을 합친다.
const onSubmit = e => {
e.preventDefault();
if (toDo === "") {
return;
}
setToDo("");
setToDos(prevArr => [toDo, ...prevArr]); // 📌여기에 추가
};
참고로, onSubmit시마다 toDos 배열에 추가되어야하므로
아까 작성했던 onSubmit 함수 맨 밑에 추가한다.
3 / 제목(heading) 추가
<h1>To Do List ({toDos.length})</h1>
즉각적으로 toDos 배열의 갯수를 셀 수 있도록 추가해봄.
지금까지의 전체 코드 🔻
App.js
import { useState } from "react";
function App() {
const [toDo, setToDo] = useState("");
const [toDos, setToDos] = useState([]);
const onChange = e => {
setToDo(e.target.value);
};
const onSubmit = e => {
e.preventDefault();
if (toDo === "") {
return;
}
setToDo("");
setToDos(prevArr => [toDo, ...prevArr]);
};
console.log(toDos);
return (
<div>
<h1>To Do List ({toDos.length})</h1>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={toDo}
type="text"
placeholder="Write your to do..."
/>
<button>Add To Do</button>
</form>
</div>
);
}
export default App;
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
part2.
toDos 배열의 각 요소를
하나하나의 컴포넌트로 만들려면?
{toDos.map(item => (
<li>{item}</li>
))}
return (
<div>
<h1>To Do List ({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 => (
<li>{item}</li>
))}
</ul>
</div>
);
>> App.js의 return부분(jsx)에 ul>li로 추가해준다.
정상적으로 잘 동작한다.
(자동으로 리스트에 추가되고, li로 생성됨)
>> toDos는 useState로 구현한 state이고,
변경된 것만 새로 li로 추가되는 것임.
잘 동작하긴 하지만, 콘솔창을 보면
list의 각 child에는 key라는 속성이 주어져야한다고 나온다.
>> 각 li마다 고유한 키값을 가져야함.
map메소드를 보면 index값이 존재한다.
각 요소의 인덱스 번호를 number로 가지고있는 값이다.
따라서 이는 고유한 key로 사용 가능하므로
{toDos.map((item, index) => (
<li key={index}>{item}</li>
))}
위와 같이 index를 매개변수로 추가한 후, key={index}를 해준다.
참고로 개발자도구 element창을 보면
li 안에 innertext 로 직접 들어간게 아니라 가상요소(::marker)로 들어간 걸 확인할 수 있다.
Ref.
Free Lecture
'PRACTICE > SELF' 카테고리의 다른 글
CSS - Flexbox prac.01 (0) | 2022.02.26 |
---|---|
React JS - Coin Tracker (project) (0) | 2022.02.19 |
React. React JS - Unit Converter (CSS추가) (0) | 2022.02.16 |
React) React JS - practice. 단위변환기 (Unit Conversion) (0) | 2022.02.15 |
CSS - Position prac.03 (0) | 2022.02.12 |