React

[리액트] Localstorage 수정하기

ejunyang 2024. 5. 24. 16:29

 

 

 

결과물

 

 

 

 

 

 

Detail.jsx

디테일 페이지에서 값을 수정하려고 한다. 내가 생각했을 땐 입력 상태를 업데이트 해주는 각 setState가 필요할 것 같았는데, useRef로 수정 기능을 많이 구현한다고 했다. 

 

useRef()를 사용해서 초기값을 먼저 설정해준다. 텍스트 수정은 input 태그에 defaultValue에 담아 데이터를 불러올 수 있다.

const dateRef = useRef(exe.date);
const itemRef = useRef(exe.item);
const descRef = useRef(exe.desc);
const amountRef = useRef(exe.amount);
<label>날짜</label>
<StInput ref={dateRef} defaultValue={exe.date} />
<label>항목</label>
<StInput ref={itemRef} defaultValue={exe.item} />
<label>내용</label>
<StInput ref={descRef} defaultValue={exe.desc} />
<label>금액</label>
<StInput ref={amountRef} defaultValue={exe.amount} />

 

 

 

 

 

 

수정할 데이터 접근

변수명.current.value로 수정할 데이터에 접근할 수 있다. 그래서 따로 수정한 데이터를 담은 객체를 생성해주었다. 

const modifiedData = {
    id: exe.id,
    date: dateRef.current.value,
    item: itemRef.current.value,
    amount: +amountRef.current.value,
    desc: descRef.current.value,
};

 

해당 월 지출내역이 있는 배열에 순회를 돌려서 해당 월 지출 내역의 id 값이 내가 수정하려는 지출 내역과 같다면 수정된 데이터가 저장되도록 했다. 여기서 계속 오류가 났었는데 이유는 아래와 같다.

 

콘솔에서 찍어보면 수정은 잘되는데 기존에 있던 데이터가 삭제되고 내가 수정한 객체가 새로운 배열로 반환되어 수정하려는 데이터와 수정한 데이터 두개만 찍히는 것이다. 

 

 

오류가 나타난 이유는 바로 map 함수를 사용하면서 해당 객체에 접근할 수 있는 매개변수를 ex로 설정해놓고 exe로 써놓았던 것.. 아직 map 함수를 정확히 이해하지 못한 것 같다^^.. 이렇게 바꾸고 다시 수정을 시도했더니 아주 잘 됐다.. .. 

const modifyExes = data[exe.month].map((ex) =>
      ex.id === id ? modifiedData : ex
);

 

 

 

👾 오류

여기서 잘되나 싶었는데 수정하고 나서 홈화면으로 나갔다가 수정했던 데이터를 다시 수정하려고 하니까 아래 오류가 나왔다. 수정 함수를 건드렸는데 onRemove() 함수에 있는 filter가 안되는 것이다. data[exe.month]를 확인해보니 undefined가 떴다. 

Uncaught TypeError: Cannot read properties of undefined (reading 'filter')

 

콘솔에 수정된 데이터 변수인 modifyExes를 찍어보니 month 값이 안찍히고 있었던 것. 그래서 data[exe.month] 찍었을 때 데이터를 불러오지 못하고 undefined가 떴구나. 

 

 

✨ 해결

수정 코드에 스프레드 연산자를 사용했다. 기존 객체에는 month가 있고, 새로 만든 수정 객체에는 month가 없기 때문에 스프레드 연산자로 합쳐주었다.

더보기

✏️ 스프레드 연산자

기존 배열이나 객체의 전체 또는 일부를 다른 배열이나 객체로 빠르게 복사할 수 있습니다. 기존에 생성되어 변수에 할당되어 있는 배열이나 객체를 새로운 변수에 할당 하게되면 새로운 변수는 기존의 변수에 할당되어 있는 객체 또는 배열을 참조하게 됩니다. 객체에서는 spread 연산자를 이용하여 객체의 프로퍼티를 업데이트 하거나 복사할 수 있습니다.

좌변엔 원본 데이터를 복사하고, 우변엔 덮어 씌울 데이터를 복사한다. 여기서 중복되는 키값은 우변으로 덮어씌워지고 새로운 프로퍼티가 있는 경우 업데이트되게 된다. 아래의 예시를 보면 이해가 쉽다.

const person1 = { name: "john", age:"18" }
const person2 = { name: "Alice", age:"20", citiy:"seoul" }

const sum = {...person1, ...person2}
//결과 : { name: "Alice", age:"20", citiy:"seoul" }

 

그렇게 바꿔준 코드이다. 콘솔에 찍어보니 month도 잘찍히는 것을 확인할 수 있다.

const modifyExes = data[exe.month].map((ex) =>
      ex.id === id ? { ...ex, ...modifiedData } : ex
);

 

 

수정한 데이터를 다시 저장해주고, 로컬스토리지에 저장해주면 완성! 수정기능을 하면서 아직 map, filter 배열과 객체를 제대로 알지 못하는 것 같았다. 잘안다고 생각했는데 코드에 활용할 때 이론이 백지가 되버린다. 제대로 더 공부해봐야겠다.

data[exe.month] = modifyExes;
localStorage.setItem("expenseList", JSON.stringify(data));