[미니 토이 프로젝트] React-Redux 이용해서 단어장 만들기 (1)
완료 버튼 / 완료하지 않았다는 버튼을 눌렀을 시, firestore와 리덕스 스토어에 completed 값을 true, false 업데이트는 시켰는 데, 화면에 반영되지 않는 문제가 있었다.
새로고침을 하면 반영이 되지만 사용자가 새로고침을 해야 반영되다보니 이 부분을 고쳐야만 했다.
해결방법으로는 업데이트를 완료시키자마자 바로 화면을 다시 뿌려주는 방식으로 해결했다.
// Card.js
// 1. 버튼 클릭시 함수 호출. 해당 카드 데이터를 같이 넘겨준다.
<Button variant="contained" color="success" onClick={() => {
completedWord(dic)
}}>공부함</Button>
// 2. dispatch해서 completedWordFB를 카드 데이터와 같이 넘겨준다.
const completedWord = async (dic) => {
await dispatch(completedWordFB(dic))
}
// redux/modules/word.js
// 3. middleware에서 completed를 update하는 부분이다.
export function completedWordFB(word) {
return async function (dispatch, getState) {
const docRef = doc(db, "words", word.id);
await updateDoc(docRef, { completed: !word.completed });
const word_list = getState().word.list;
const word_index = word_list.findIndex((w) => {
return w.id === word.id;
})
dispatch(completedWord(word_index));
// 원래는 completedWord까지 있었지만
// 화면을 뿌려주는 dispatch를 바로 실행시켜버린다.
dispatch(loadWordFB());
}
}
메인페이지에서 수정하기 페이지로 넘어가고 수정하기 기능도 잘 작동되었다. 그런데 수정하기 페이지에서 새로고침을 하면 페이지가 날라가는 문제가 생겼다.
에러 코드만 보면 리덕스 스토어에서 데이터를 받아와야하는데, 리덕스 자체를 찾지를 못했다.
새로고침을 하면 리덕스 store의 state가 날라가는 문제인데 redux persist
를 이용해서 문제를 해결할 수 있었다.
이 라이브러리를 사용하면 store의 state를 localstorage나 session에 저장해놓고 불러올 수 있어서, 새로고침을 해도 데이터가 사라지지 않았다. (방법을 알려주신 팀원분에게 감사를!)
카드를 추가하는 기능을 사용하면 메인페이지로 돌아오게 되는데 콘솔에서 이상한 경고가 떴다.
Warning: Encountered two children with the same key,
Xa0cQPMERZTDtRqTsYU8
. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
분명 코드로는 데이터를 하나 넣었고 firestore에서는 데이터 하나당 특정 id를 부여해주는데, 그 행동이 2번 중복되어서 id가 중복되었다는 경고라고 생각했다.
이유를 알 수 없었는데 코드를 조금 손보니까 고칠 수 있었다.
// redux/modules/word.js
// reducer에서 생성하는 부분 이전 코드
case "words/CREATE": {
const new_word_list = [...state.list, action.word_data];
console.log(new_word_list)
➊ return { ...state, list: new_word_list };
}
// redux/modules/word.js
// reducer에서 생성하는 부분 바꾼 코드
case "words/CREATE": {
const new_word_list = [...state.list, action.word_data];
console.log(new_word_list)
➊ return { list: new_word_list, ...state };
}
솔직히 말하면 이 두 개의 차이점이 뭔지 모르겠다..
실제로 테스트 코드를 작성해봤지만 순서외에는 차이점이 없었는데 그 차이가 이 코드에서 왜 에러를 뱉고 뱉지 않는지 이해를 못한 상황이다.