현재 useReducer로 만든 프로젝트를
중앙 집중적 전역상태 관리를 위해 RTK으로 리팩토링하는 중이다.
(쓰이는 용어는 비스무리 하지만, 다른 점이 있어서 리팩토링 하면서 배우는중~)
그런데, Components에 보이는 것처럼 TodoCard(-TodoItem) , CompletedCard(-CompletedItem)
각각 컴포넌트를 만들었음에도 불구하고, 문제가 생겼다.
TodoCard의 모달창을 열어서 정보를 입력하면, CompletedCard 아래에 메모가 누적된다는 점이다.
타겟이 잘못되었나 싶어 import와 export 등을 확인했지만, 경로 문제는 없었고,
오타의 문제도 아니었다...
데브툴을 봐도, 자꾸 modalCompletedItem이 업데이트 되는 상황이다...
const Health = () =>{
return(
<CardContainer>
<TodoCard/>
<CompletedCard/>
</CardContainer>
)
};
export default Health;
공통적으로 가진 변수명때문에 문제가 되는건가? 해서 찾아보니
같은화면에서 렌더링시, 변수 작명에 주의해야한다는 것이다.
modalContent를 각각의 <TodoCard/>와 <CompletedCard/>에서 사용할 때, 이름을 구분하기 위해 다르게 작명했다
이후에도 추가적으로 해결할 문제가 있나보다
결론적으로, 문제가 아직 해결이 안되었다.. (절망중...)
그래서, 다음으로 시도해본것이 공통적으로 가진 state였다.
사실, 문제를 바로 찾아내지는 못했는데,,,,
해볼 수 있는 시도를 다 해본 상태에서는 당연하다고 여겼던 코드를 의심해보는 것이 문제해결에 좋다!
const TodoCard = () =>{
const modalOpen = useSelector((state)=> state.modalOpen) // 두 컴포넌트에서 이 state를 공유하고 있었다.. 이런,,
const todoModalContent = useSelector((state)=> state.todoModalContent)
const dispatch = useDispatch()
return (
<Card >
<Title>To do</Title>
<div onClick={()=>dispatch(modalIsOpen())} className ="pluscontainer">
<img src={plus} alt='icon'></img>
</div>
{ modalOpen.showModal ? <TodoModal todoModalContent={todoModalContent} onClick={()=>modalIsClose()}/>: null}
{/* 컴포넌트에 onClick을 props로 내려준것이니 모달컴포넌트로 가서 직접 이벤트를 작성해야 한다 */}
<TodoItem todoModalContent={todoModalContent}/>
</Card>
)
};
export default TodoCard;
const CompletedCard = () =>{
const CompletedCard = () =>{
const modalOpen = useSelector((state)=> state.modalOpen)//공통으로 사용하고 있는 상태... 이런,,
const completedModalContent = useSelector((state)=> state.completedModalContent)
const dispatch = useDispatch()
//console.log(completedModalContent)
return (
<Card>
<Title>Completed</Title>
<div onClick={()=>dispatch(modalIsOpen())} className ="pluscontainer">
<img src={plus} alt='icon'></img>
</div>
{ modalOpen.showModal ? <CompletedModal completedModalContent={completedModalContent} onClick={()=>modalIsClose()}/>: null}
{/* 컴포넌트에 onClick을 props로 내려준것이니 모달컴포넌트로 가서 직접 이벤트를 작성해야 한다 */}
<CompletedItem completedModalContent={completedModalContent}/>
</Card>
)
};
export default CompletedCard;
const modalOpen = useSelector((state)=> state.modalOpen) 부분을 삭제하고,
각각 state를 만들어줬다.
const TodoCard = () =>{
// state는 reducer로 관리하고, dispatch는 reducer를 호출시켜 initialState를 업데이트 시키는 매개체가 된다
const [showTodoModal, setShowTodoModal] = useState(false); //각각 만들어준 state
const todoModalContent = useSelector((state)=> state.todoModalContent)
console.log(todoModalContent)
return (
<Card >
<Title>To do</Title>
<div onClick={()=>setShowTodoModal(true)} className ="pluscontainer">
<img src={plus} alt='icon'></img>
</div>
{ showTodoModal ? <TodoModal todoModalContent={todoModalContent} closeModal={()=>setShowTodoModal(false)}/>: null}
{/* 컴포넌트에 onClick을 props로 내려준것이니 모달컴포넌트로 가서 직접 이벤트를 작성해야 한다 */}
<TodoItem todoModalContent={todoModalContent}/>
</Card>
)
};
export default TodoCard;
const CompletedCard = ()=>{
const [showCompletedModal, setShowCompletedModal] = useState(false); //각각 만들어준 state
const completedModalContent = useSelector((state)=> state.completedModalContent)
return (
<Card >
<Title>Completed</Title>
<div onClick={()=>setShowCompletedModal(true)} className ="pluscontainer">
<img src={plus} alt='icon'></img>
</div>
{ showCompletedModal ? <CompletedModal completedModalContent={completedModalContent} closeModal={()=>setShowCompletedModal(false)}/>: null}
{/* 컴포넌트에 onClick을 props로 내려준것이니 모달컴포넌트로 가서 직접 이벤트를 작성해야 한다 */}
<CompletedItem completedModalContent={completedModalContent}/>
</Card>
)
};
export default CompletedCard;
그랬더니 정상적으로 작동되었다.
다른 컴포넌트에 덮어씌워지는 현상이 나타난다면 부적절하게 state를 공유하고 있는지를 확인하고,
각각 독립적으로 작동될 수 있는 state를 정의하는 것이 필요하다
요약
1. 같은 화면 렌더링시, 공통적으로 가진 변수명이 문제가 될 수 있다 (특히, 액션 변수)
2. 각 컴포넌트는 독립적으로 작동될 수 있는 state를 정의하는 것이 필요하다
'React' 카테고리의 다른 글
fetch 보다 axios를 쓰는 이유 (0) | 2023.07.05 |
---|---|
setState 함수 호출 이후에 상태값을 바로 사용못함 (0) | 2023.06.21 |
useReducer와 Redux의 차이점 (0) | 2023.06.09 |
Invalid hook call 오류 (0) | 2023.06.08 |
Storybook 문서화하기 (2) | 2023.05.24 |