brunch

You can make anything
by writing

C.S.Lewis

by 홍기린 Dec 20. 2023

localStorage를 사용해서 투두 앱 만들기

with React

최근에 리액트로 투두앱 만드는 연습을 했다. 만난 적은 없지만 거의 나에게는 멘토같은 Ellie (엘리의 드림코딩) 의 강의를 들으며 실습을 했다. 강의 내용 중에 localStorage를 사용해서 투두 리스트를 브라우저에 간단하게 저장하는 걸 보게 됏는데, 너무 간단하고 간편해서 메모해둔다 :)


투두앱 실습 결과물 보기 >>

투두를 만들고 페이지 이동을 했다가 돌아와도 여전히 투두가 남아있돠



localStorage란?


localStorage는 웹 브라우저에서 제공하는 클라이언트 측 웹 스토리지다. 이걸 사용해서 웹 애플리케이션에서 데이터를 로컬에 저장하고, 혹은 다시 꺼내 사용할 수 있다. 일반적으로 다른 데이터베이스와는 다르게 비교적 작은 양의 데이터를 저장하기 위해 사용된다. 이 데이터는 사용자가 해당 웹 사이트를 방문할 때마다 로드되고, 세션 제한이 없어서 브라우저를 닫아도 데이터는 계속 유지된다.


localStorage를 사용하면 키-값 쌍으로 데이터를 저장할 수 있다. 예를 들어, 다음과 같이 코드를 작성하여 'todoItem'이라는 키에 '강아지랑 산책하기'라는 값을 저장할 수 있다


localStorage.setItem('todoItem', '강아지랑 산책하기');

위에 저장된 값을 가져오려면 키 값으로 꺼내올 수 있다.


const item = localStorage.getItem('todoItem');
// item 값은 '강아지랑 산책하기'



프로젝트에서 응용하기


투두앱에서 localStorage에 저장해야되는 건 todos, 단순 문자열이 아니라 배열이다. 그래서 배열을 JSON.stringify 함수로 변환해서 저장해준다.


localStorage.setItem('todos', JSON.stringify(todos))
// todos = [{id:1, text:'강아지랑 산책시키기'}, ...]
// JSON.stringify(todos) = '[{id:1, text:'강아지랑 산책시키기'}, ...]'
// JSON.stringify() 는 object든 array든 String 형태로 바꾸어준다.


리액트 TodoApp에서 todos 값이 변경될때마다 업데이트해주면 되니까, useEffect 함수 안에 정의해준다. 

useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(todos))
}, [todos]) // todos가 바뀔때마다 실행된다


처음 todos를 불러올때, 이미 브라우저의 localStorage에 저장되어있는 값이 있다면 그걸 불러오고, 아니면 빈 배열([])을 가져와야 하므로, 처음 useState를 할때, 아래와 같이 localStorage로부터 값을 찾는다. 그리고 그걸 다시 JSON.parse로 배열을 만들어준다.



function readTodosFromLocalStorage() {
  const todos = localStorage.getItem('todos')
  return todos ? JSON.parse(todos) : []
}
const [todos, setTodos] = useState(() => readTodosFromLocalStorage())

* 여기서 주의해야 할 게, useState 안에서 바로 useState(readTodosFromLocalStorage()) 이렇게 콜 하면 안된다는 점이다. 그러면 컴포넌트가 투두가 하나씩 추가될때마다 readTodosFromLocalStorage 함수가 계속 실행된다. useState라는 게 기존의 값을 기억해서 거기에 자동으로 추가된 부분만 기억해서 업데이트해주는 기능인데, 이미 불러온 todos를 다시 localStorgae에서 불러올 필요가 없다. 그래서 처음 init state할 때만 해당 콜백함수가 실행되고, 그 후로는 실행되지 않는다. (좀 어려웠다)





브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari