휘발성 메모리
: 자바스크립트의 기능을 활용해서 React의 State 값을 추가적으로 저장하더라도 자바스크립트는 클라이언트 사이드인 웹 브라우저에서만 동작하는 그런 데이터
이므로 새로고침하게 되면 가지고 있던 것을 싹 비운 다음 새로 다시 받기 때문에 그런 과정에서 데이터들은 초기화 된다. 그런데 현재 우리는 DB가 없고, DB를 배우지 않았는데..?!
이럴 때 굉장히 쉽고 간단하게 비용을 들이거나 추가적인 노동없이 사용할 수 있는 DB가 하나 존재하는데...
Web Storage API
Key와 Value를 쌍으로 저장
하는데, Web Storage에는 sessionStorage와 LocalStorage가 있다.LocalStorage
: sessionStorage와 달리 브라우저가 꺼져도 데이터가 남아있다
. 유효기간 없이 데이터를 저장하고 자바스크립트를 사용하거나 브라우저 캐시 또는 로컬 저장 데이터를 지워야만 사라진다. (작성한 일기 데이터를 내 브라우저에 남겨둘 수 있다)크롬 개발자도구(F12) > Application 탭 > Storage > Local Storage의 3000포트
Mount 됐을 때
LocalStorage에 저장된 데이터를 확인하기src/App.js
function App() {
useEffect(()=>{
localStorage.setItem("item1", 10);
localStorage.setItem("item2", "20");
localStorage.setItem("item3", JSON.stringify({value:30}));
}, []);
function App() {
useEffect(()=>{
const item1 = localStorage.getItem("item1");
const item2 = localStorage.getItem("item2");
const item3 = JSON.parse(localStorage.getItem("item3"));
console.log({item1, item2, item3});
}, []);
const [data, dispatch] = useReducer(reducer, []);
Reducer
const reducer = (state, action) => {
let newState = [];
switch(action.type){
case "INIT" : {
return action.data;
}
case "CREATE" : {
// const newItem = { ...action.data };
newState = [action.data, ...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;
}
// reducer를 거쳐서 일기 렌더링
// newState가 return되기 전 localStorage에 저장 (직렬화)
localStorage.setItem("diary", JSON.stringify(newState));
return newState;
};
src/components/DiaryEditor.js
<MyHeader
headText={isEdit ? "일기 수정하기" : "새 일기쓰기"}
leftChild={<MyButton text={"< 뒤로가기"} onClick={()=>navigate(-1)} />}
rightChild={isEdit && (<MyButton text={"삭제하기"} type={"negative"} />)}
/>
// 삭제하기 onRemove 공급
const {onCreate, onEdit, onRemove} = useContext(DiaryDispatchContext);
// 삭제하기
const handleRemove = () => {
if(window.confirm("정말 삭제하시겠습니까?")) {
onRemove(originData.id);
navigate('/',{replace:true});
}
};
<MyHeader
headText={isEdit ? "일기 수정하기" : "새 일기쓰기"}
leftChild={<MyButton text={"< 뒤로가기"} onClick={()=>navigate(-1)} />}
rightChild={isEdit && (<MyButton text={"삭제하기"} type={"negative"} onClick={handleRemove} />)}
/>
useEffect(()=>{
const localData = localStorage.getItem("diary");
if(localData) {
const diaryList = JSON.parse(localData).sort(
(a,b) => parseInt(b.id) - parseInt(a.id)
);
dataId.current = parseInt(diaryList[0].id) + 1
// 초기값을 설정해주는 액션
dispatch({type:"INIT", data:diaryList});
}
}, []);
// key 초기값 변경
const dataId = useRef(0);
💬 이제 최적화 후 배포&빌드만 남음!!