변경전 초기 코드 다운받기(git)
git clone https://github.com/gusrl6394/context-todo-list
cd context-todo-list
git reset --hard 2f89bca4ec8f1399a34e232835b2e66daa79a702
localStorage
- ContextAPI를 사용하여 컨텍스트를 만들고 전역으로 데이터를 관리하도록 변경해보았으며 이렇게 관리되는 데이터를 외부에 저장하는 방법중 하나인 localStorage를 알아보자
- 보통 웹 서비스에서는 이런 데이터를 API를 통해 서버에 저장하고 가져온다. 이것은 추후 연습해보기로 한다.
변경된 부분)
Contexts/ToDoList/indes.tsx
import React, {createContext, useState, useEffect} from "react";
const addToDo = (toDo: string): void => {
if(toDo) {
const newList = [...toDoList, toDo];
localStorage.setItem('ToDoList', JSON.stringify(newList));
setToDoList(newList);
}
};
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
}, []);
- useEffect는 함수 컴포넌트에서 클래스 컴포넌트의 라이프 사이클 함수와 비슷한 역할을 하는 훅이다.
- 실행될 내용이 담긴 콜백 함수를 첫 번째 매개변수
- useEffect가 의존하는 변수들을 배열 형식으로 설정한 두 번째 매개변수
- localStorage에는 문자열 데이터만 저장할 수 있다. 따라서 저장한 문자열 데이터를 우리가 원하는 배열 데이터로 변경하기 위해 JSON.parse를 사용한다.
결과
- 새로고침하여도 데이터가 남아있는것을 볼 수 있다.
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
}, []);
- 두번째 매개변수에 빈 배열을 전달하게 되면 클래스 컴포넌트의 componentDidMount와 같은 역할을 수행, 즉 컴포넌트가 처음 화면에 표시된 후에 useEffect는 한 번만 호출하게된다.
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
});
- 두 번째 매개변수를 설정하지 않는 경우 componentDidMount 와 componentDidUpdate의 역할을 동시에 수행
- 컴포넌트가 처음 화면에 표시된 후에도 실행되며 Props나 State의 변경으로 컴포넌트가 리렌더링된 후에도 실행된다
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
return () => {
...
}
});
- 반환함수는 componentWillUnmount와 마찬가지로 라이브러리와의 연동을 해제하거나, 타이머를 해제하는 데 사용된다.
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
},[toDoList]);
- useEffect만의 고유한 기능
- 두 번째 매개변수 배열에 특정 변수를 설정하여 전달하면 모든 Props와 State에 변경에 호출되는 componentDidUpdate와 다르게 전달된 변수가 변경될 때만 이 함수가 호출되도록 설정할 수 있다
- 두 번째 매개변수로 toDoList 값에 변경 사항이 발생하면 이 변경 사항을 감지하고 useEffect의 콜백 함수를 실행하게 된다.
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
},[]);
useEffect(() => {
const list = localStorage.getItem('ToDoList');
if(list) {
setToDoList(JSON.parse(list));
}
},[toDoList]);
- useEffect는 클래스 컴포넌트의 라이플 사이클 함수와 다르게 한 컴포넌트 안에서 여러 번 정의하여 사용할 수 있다. 따라서 componentDidMount의 역할을 하는 useEffect와 특정 변수의 값이 변경될 때 실행되는 로직을 위한 useEffect를 함께 사용할 수 있다
'2022 > 리액트+TDD(完)' 카테고리의 다른 글
react-router (0) | 2022.02.12 |
---|---|
Context API / localStorage TestCode (0) | 2022.01.16 |
Context API / localStorage - 1 (0) | 2022.01.14 |
클래스 컴포넌트 라이프 사이클 (0) | 2022.01.13 |
함수 컴포넌트에서 클래스 컴포넌트 변환 (0) | 2022.01.12 |