DEV/WebProgramming

[React] Local Storage

9thxg 2022. 7. 8. 18:01

 

인프런, 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지의 내용 중 Local Storage에 대해 내용을 정리한다.

 

목차
  1. Web Storage API 사용하기
  2. Local Storage 확인하기
  3. 프로젝트에 적용하기

 


Web Storage API 사용하기

 

따로 데이터 베이스가 없다면 페이지를 테스트하고 난 후 껐다 켜거나 새로고침 할 경우 데이터가 처음 그대로 돌아가게 된다. 이럴 때 Web Storage API를 사용하여 LocalStorage에 데이터를 저장시키고 불러와 데이터를 보존한다.

Web Storage API에는 두 가지로 나뉜다. session storage와 local storage가 있으며 session storage는 브라우저가 열려있는 동안 데이터를 보존하고 local storage경우 브라우저를 닫았다 열어도 유지되도록 한다. local storage의 데이터는 브라우저 캐시 또는 저장된 로컬 데이터를 삭제하지 않으면 계속 유지된다.

 

Local Storage 저장 및 불러오는 방법은 setItem 함수로 키와 값을 지정하여 저장한다. 만약 객체인 값을 저장할 때는 브라우저에서 사용할 수 있도록 JSON.stringify 함수를 통해 직렬화를 해주어 저장한다. getItem 함수에 키 이름을 통해 값을 받아오고 만약 받아오는 값이 객체라면 직렬화된 객체의 값을 JSON.parse를 통해 다시 객체로 만들어주어 불러온다.

또한, 불러올 때 브라우저에 저장된 값은 문자열로 저장되기 때문에 실수나 정수 등의 경우 함수를 통해 형변환하여 불러온다.

useEffect(() => {
	localStorage.setItem("Key", Value);
    
    localData = localStorage.getItem("Key");
}, []);

// 만약 객체인 데이터를 저장하고 불러오는 경우
useEffect(() => {
	localStorage.setItem("diary", JSON.stringify(newState));
    
    localData = localStorage.getItem("diary");
    const diaryList = JSON.parse(localData);
}, []);

 


 

Local Storage 확인하기

 

Local Storage에 저장된 값을 확인하는 방법은 "개발자 도구 - Application탭 - Storage - Local Storage"에서 확인이 가능하다.

 


 

프로젝트에 적용하기

 

해당 프로젝트에선 reducer를 통해 모든 상태 변환 로직이 거쳐가기 때문에 reducer에서 Local Storage를 관리해주면 된다. 또한 페이지를 불러올 때 즉 마운트 될 때 Local Storage값을 불러와 갱신해준다.

reducer 부분에 상태변화를 적용하기 전에 setItem함수를 사용하여 현재 상태를 Local Storage에 저장한다.

불러올 때는 Local Storage에 저장된 데이터가 없을 수 있기 때문에 if문을 통해 처리해준다. id값을 처리하기 위해 받아온 데이터를 id가 큰 순으로 정렬해주고 현재 id값을 불러온 첫 데이터의 id값보다 1 크게 만들어 사용한다. 이후 dispatch를 통해 불러온 데이터를 적용해준다.

// App.js
const reducer = (state, action) => {
  let newState = [];
  switch (action.type) {
    case "INIT": {
      return action.data;
    }
    case "CREATE": {
      const newItem = {
        ...action.data,
      };
      newState = [newItem, ...state];
      break;
    }
    case "REMOVE": {
      newState = state.filter((it) => it.id !== action.targetId);
      break;
    }
    case "EDIT": {
      newState = state.map((it) =>
        it.id === action.data.id ? { ...action.data } : it
      );
      break;
    }
    default:
      return state;
  }

  localStorage.setItem("diary", JSON.stringify(newState));
  return newState;
};

function App() {
  // 처음 데이터는 빈 배열로 넘겨준다.
  const [data, dispatch] = useReducer(reducer, []);

  const dataId = useRef(0);

  useEffect(() => {
    const localData = localStorage.getItem("diary");
    // Local Storage에 저장된 데이터가 없을 수 있으므로 if문을 사용하여 처리한다.
    if (localData) {
      // id 값을 지정해주기 위해 Local Data를 받아올 때 id가 큰 순으로 정렬한다.
      const diaryList = JSON.parse(localData).sort(
        (a, b) => parseInt(b.id) - parseInt(a.id)
      );
      if (diaryList.length >= 1) {
        dataId.current = parseInt(diaryList[0].id) + 1;
		
        // reducer의 INIT을 통해 데이터를 불러온다.
        dispatch({ type: "INIT", data: diaryList });
      }
    }
  }, []);
};