[내일배움캠프 TIL] 62일차

Jaehyeon Ye·2023년 1월 24일
0

이번 프로젝트에서는 컴포넌트 재사용성과 코드 가독성 및 구조에 신경쓰려다보니 page 컴포넌트로부터 버튼과 input 컴포넌트를 각각 분리하려다보니 input컴포넌트에 입력된 값을 버튼 컴포넌트에 전달해야했다. 하지만 버튼 컴포넌트가 input 컴포넌트로부터 props를 받게 되면 부모, 자식 관계가 되는 것인데 생각하기에는 서로 형제 컴포넌트라고 생각되고 그러기에 버튼 컴포넌트가 props로 의존성있는 컴포넌트가 되지 않도록 전역 상태로 관리해줘야겠다고 생각해서 redux 툴킷을 도입하였다. (contextAPI는 컴포넌트 재사용성 측면에서 좋지 않다고 하였고 최상위 컴포넌트에서 시작하기에 최하위 컴포넌트인 input 입력값을 받아 전역에 반영하기엔 적절하지 않다고 생각하였다. recoil은 아직 사용방법을 익히지 못해서 사용하지 못했다.)

문제는 useSelector로 버튼 컴포넌트에 전역 상태를 가져오려고 하는데 store와 slice에서 각각 타입을 지정해줬음에도 불구하고

	type userAction = ReturnType<typeof updateUserInfo>;
interface stateType {
  userNickname: string;
  currentPwd: string;
  newPwd: string;
  confirmNewPwd: string;
}

const initialState: stateType = {
  userNickname: 'Visitor',
  currentPwd: '',
  newPwd: '',
  confirmNewPwd: '',
};

const userSlice: any = createSlice({
  name: 'user',
  initialState,
  reducers: {
    updateUserInfo: (state, action: userAction) => {
      state = action.payload;
    },
  },
});

export const { updateUserInfo } = userSlice.actions;
export default userSlice.reducer;

//....

 const userInfo = useAppSelector((state) => state.user);

위의 userInfo값이 콘솔에는 initialState가 잘 찍히지만 unknown 타입으로 넘어와서 이 값을 사용하려고 하면 에러가 발생한다는 점과 input 태그에 e.target.value로 전역 상태에 실시간 반영되도록 dispatch(updateUserInfo(e.target.value))를 해도 반영되지 않는다는 점이다.

어떻게 해결해야할지 모르겠다.

다른 한 가지는 부모로부터 props를 받아서 JSX Element를 switch case로 리턴해주냐 아니면 props 없이 통으로 return하냐에서 발견한 차이이다. 부모로부터 계속 변하는 props(input의 label값)로 인해 자식 컴포넌트인 input 컴포넌트의 리렌더링이 발생해서 state가 초기화되는 것으로 알고있다. 이로 인해 비밀번호가 일치하는지 확인하는 기능을 구현하는데 있어서 input의 focus가 달라지면 이전에 focus되어있던 input에 입력한 state가 초기화되고 결국 비교를 하지 못하는 문제점이 발생했다.

부모 컴포넌트에서 객체값을 props로 넘겨주는 게 아니기에 useMemo를 사용하진 못했고 input 컴포넌트에 React.memo도 적용해봤지만 현상은 동일했다. 일단 비밀번호 일치 여부 판단에서 원하는 결과를 얻기 위한 조치로 재사용성을 위해 경우에 따라 컴포넌트를 리턴해주도록 하는 props를 받지 않고 switch case로 리턴해주던 컴포넌트를 통으로 리턴하는 방식으로 변경하긴 했지만 추후에 개선되어야할 부분이다.

profile
FE Developer

0개의 댓글