초보자의 입장에서 적은 내용으로, 틀리거나 정확하지 않을 수 있습니다.
[리액트] 노마드코더 투두리스트(Todo list) 복습
공부 기간: 22/03/31
결과
import { useState } from "react";
export default function App() {
const [todo, setTodo] = useState("");
const [todos, setTodos] = useState([]); // [] 리스트임을 표기하는 것 뿐임. 어차피 () 안에 통째로 todos가 되는거라 list를 받으면 알아서 todos에 리스트 전달됨.
const onChange = (event) => {
setTodo(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
if (todo === "") {
return;
} else {
setTodos((current) => [...current, todo]);
setTodo("");
}
};
return (
<>
<h1>Todos : {todos.length}개</h1>
<form onSubmit={onSubmit}>
<input placeholder="할일입력" value={todo} onChange={onChange} />
<button>Add</button>
</form>
{todos.map((element, index)=><li key={index}>{element}</li>)}
</>
);
}
해결방안
1. form태그로 감싼 input태그 만들기, submit 시 내용 출력되도록 만들기
export default function App() {
const [value, setValue] = useState("");
const onChange = (event) => {
setValue(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
console.log(value)
}
return (
<>
<form onSubmit = {onSubmit}>
<input placeholder="할일입력" value={value} onChange={onChange}></input>
<button>Add</button>
</form>
</>
);
}
2. spread연산자를 이용해 할일(todos) 저장해두는 배열 state만들기
export default function App() {
const [todo, setTodo] = useState("");
const [todos, setTodos] = useState([]); // [] 리스트임을 표기하는 것 뿐임. 어차피 () 안에 통째로 todos가 되는거라 list를 받으면 알아서 todos에 리스트 전달됨.
const onChange = (event) => {
setTodo(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
if (todo === "") {
return;
} else {
setTodos((current) => [todo, ...current]);
setTodo("");
}
};
return (
<>
<h1>{todos.length}</h1>
<form onSubmit={onSubmit}>
<input placeholder="할일입력" value={todo} onChange={onChange}></input>
<button>Add</button>
</form>
</>
);
}
3. 할일 저장돼있는 todos 배열 state를 이용해 li태그로 렌더링해주기
import { useState } from "react";
export default function App() {
const [todo, setTodo] = useState("");
const [todos, setTodos] = useState([]); // [] 리스트임을 표기하는 것 뿐임. 어차피 () 안에 통째로 todos가 되는거라 list를 받으면 알아서 todos에 리스트 전달됨.
const onChange = (event) => {
setTodo(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
if (todo === "") {
return;
} else {
setTodos((current) => [...current, todo]);
setTodo("");
}
};
return (
<>
<h1>Todos : {todos.length}개</h1>
<form onSubmit={onSubmit}>
<input placeholder="할일입력" value={todo} onChange={onChange} />
<button>Add</button>
</form>
{todos.map((element, index)=><li key={index}>{element}</li>)}
</>
);
}
비고
강의 내용에 삭제버튼 추가했다.
1. todos를 map으로 찍어줄 때 button태그도 함께 생성했다. 그리고 버튼에 클릭이벤트를 부여하여 클릭시 부모 엘리먼트를 삭제해주면 된다.
import { useState } from "react";
export default 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;
} else {
setTodos((current) => [...current, todo]);
setTodo("");
}
};
const onDelete = (event) => {
event.target.parentElement.remove();
}
return (
<>
<h1>Todos : {todos.length}개</h1>
<form onSubmit={onSubmit}>
<input placeholder="할일입력" value={todo} onChange={onChange} />
<button>Add</button>
</form>
{todos.map((element, index) => {
return (
<li key={index}>{element}<button onClick={onDelete}>delete</button></li>
);
})}
</>
);
}
하지만 이렇게하면 배열 내부 엘리먼트 자체가 삭제되는 것이 아니기 때문에 todos.length는 그대로 남아있다.
2. 단순히 부모엘리먼트 삭제가 아닌 배열 내부의 데이터를 삭제하고 싶을 땐 filter를 사용하여 todos 배열을 바꿔준다.
const onDelete = (index) => {
setTodos(todos.filter((item, todoindex) => index !== todoindex));
}
return (
<>
<h1>Todos : {todos.length}개</h1>
<form onSubmit={onSubmit}>
<input placeholder="할일입력" value={todo} onChange={onChange} />
<button>Add</button>
</form>
{todos.map((element, index) => {
return (
<li key={index}>{element}<button onClick={() => onDelete(index)}>delete</button></li>
);
})}
</>
);
이렇게 해주면 된다.
(onDelete 이벤트가 활성화되면 그 엘리먼트의 index가 onDelete함수에 전달된다. 그리고 filter함수와 setTodos를 통해 todos를 새로 만들어주는데, filter함수가 배열의 모든 엘리먼트를 하나씩 가져와서 엘리먼트의 인덱스가 전달받은 인덱스와 동일하면 그 엘리먼트는 제외하고 todos를 설정해주는 것이다.)
참고로 버튼태그 이벤트에서 onClick={() => onDelete(index)} 가 아닌 onClick={onDelete(index}로 하면 안된다.
후자처럼 만들면 이벤트 만들어짐과 동시에 onDelete함수가 실행되기 때문에 여태 괄호를 빼고 onClick={onDelete} 처럼 만들었으나, 위 이벤트에는 반드시 index라는 파라미터를 받아와야 하므로 사용하고싶으면 전자처럼 사용해야한다.
*memo
- filter 함수도 map 과 마찬가지로 두번째 파라미터에 index를 받을 수 있다.
'강의 정리 > 기타 강의 정리' 카테고리의 다른 글
[Git] 2. 시간 여행하기 (0) | 2022.10.17 |
---|---|
[Git] 1. 시작하기 (0) | 2022.10.17 |
[리액트] 노마드코더 영화 추천 앱(Movie App) 복습 (0) | 2022.04.01 |
[리액트] 노마드코더 코인트래커(Coin Tracker) 복습 (1) | 2022.03.31 |
[리액트] 노마드코더 거리변환기(Km to Miles) 복습 (0) | 2022.03.30 |