- 일시 : 23.06.26 월요일
바닐라js로 코딩했던 todolist와 날씨를 리액트를 이용하여 새로 코딩해 보았다.
날씨는 리액트로 나타낼때
navigator.geolocation.getCurrentPosition()
위 함수를 사용하여 점에서 크게 다른 점은 없었고, 리액트 특징인 useState와 useEffect의 리액트 훅을 사용한다는 것에서 차이가 있었다. useState는 상태값을 관리해주고, useEffect는 컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 한다.
todolist를 리액트로 바꾸는 과정도 수월할 것이라고 생각했으나 이 글을 쓰기까지 3일이 걸리게 만든 기능이었다. 이전에 바닐라js로 구현했던 부분에서는 목록을 나타내기 위해서는
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
위와 같이 id와 text를 가진 객체를 빈 배열안에 push 해주었고, 글 삭제는 클릭된 버튼 부모의 id와 같은 id를 목록에서 filter()를 통해 삭제(처럼 보이게) 해주면 되었다.
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
그리고 이 기능들을 react에서는 상태관리 useState를 통해 더 쉽게 나타낼 수 있었다. 바닐라js에서 배열에 push했던 방식은, 다음과 같이 전개구문을 활용하여 이전 값과 함께 다시 리스트에 넣어줄 수 있었다.
setTodoList((oldList) => [newTodoObj, ...oldList])
삭제는 이전 방식과 동일하게 filter와 id를 사용하여 처리할 수 있었다.
(작성일: 23.06.29)
다만 문제는 로컬스토리지에 저장할 때 아주 다양한 문제를 맞닥뜨렸는데,
https://codingapple.com/forums/topic/localstorage-데이터가-지워집니다/
https://velog.io/@tchaikovsky/REACT-localstorage가-바로-저장되지-않는다면
하지만 어떠한 것도 답이 되지 못했다. 아무래도 새로고침 하면서 빈 배열이 로컬스토리지에 저장되는 프로세스가 작동한 것 같은데 그 문제 코드를 아직 찾지 못했다. 더 지체하면 이 글을 쓰지 못할 것 같아서 일단 기록해 놓기 위해 적어보았다. 문제 코드와 화면은 아래 과제 내용에 영상을 첨부한다.
// Todo.jsx
// 이 코드는 버그가 있습니다. (수정 전)
import { useEffect, useState } from "react";
const TodoList = () => {
const TODOS_KEY = "todos";
const [todoList, setTodoList] = useState([]);
const [todo, setTodo] = useState("");
// localStorage 불러오기
useEffect(() => {
const savedList = localStorage.getItem(TODOS_KEY);
if (savedList !== null) {
setTodoList(JSON.parse(savedList));
}
}, []);
// localStorage 저장
useEffect(() => {
localStorage.setItem(TODOS_KEY, JSON.stringify(todoList));
}, [todoList]);
const onChange = (e) => {
setTodo(e.target.value);
};
const onSubmit = (e) => {
e.preventDefault();
if (todo === "") {
return;
}
const newTodoObj = {
text: todo,
id: Date.now(),
};
setTodoList((oldList) => [newTodoObj, ...oldList]);
setTodo("");
};
const deleteTodo = (e) => {
setTodoList(
todoList.filter((item) => item.id !== parseInt(e.target.parentElement.id))
);
};
return (
<div>
<h1>My To Dos ({todoList.length})</h1>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={todo}
type="text"
placeholder="Write your to do..."
/>
</form>
<ul>
{todoList.length !== 0
? todoList.map((item, index) => (
<li key={index} id={item.id}>
<span>✅{item.text}</span>
<button onClick={deleteTodo}>🗑️</button>
</li>
))
: "no data"}
</ul>
</div>
);
};
export default TodoList;
본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.