Today목표 : 4/22일 리덕스 실습 및 이해, styled-component 리팩토링
알게된 점,
Redux 상태관리 state의 구조✅
state를 처음에는 다음과 같이 배열로 구상하였다.
const initialTodos = [
{
id: 1,
title: "리액트 공부중",
text: "재밌는 리액트 공부하기!",
isDone: false,
},
];
리턴도 역시 배열로 리턴해 주었었다.
export const todos = (state = initialTodos, action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.payload];
case DELETE_TODO:
const deletedTodos = state.filter((todo) => todo.id !== action.payload);
return deletedTodos;
case TOGGLE_CHANGE:
const changedTodos = state.map((todo) => {
if (todo.id === action.payload) {
return {
...todo,
isDone: !todo.isDone,
};
}
return todo;
});
break;
state를 배열로 만든 이유는 todos는 todolist에서 더 확장될 가능성은 없어 보여 useState에서 사용했던 대로 하나의 형식에 맞게 독립적인 배열 state로 두고 관리해야 한다고 생각했었다.
그런데, 컴포넌트에서 todos state를 그냥 가져오기만 했는데 다음과 같은 에러가 났다.
function Modal() {
const params = useParams();
const todo = useSelector((state) => state.todos);
console.log(...todo);
return <>{todo}</>;
}
❗"개체는 React 하위 개체로 사용할 수 없습니다(키가 {id, 제목, 텍스트, isDone}인 개체 발견). 하위 컬렉션을 렌더링하려면 배열을 대신 사용합니다." => 나는 todos배열 내부에 객체 형식으로 todo를 넣어 주었는데..? key가 배열이라고 인식하는건가..? 도대체 왜..? 한시간 동안 계속되는 디버깅 끝에 든 생각은..
1. 에러와 관계는 없지만, 혹시 todos 위에 객체로 감싸져 있는 것인가? 해서 혹시나 하여 store파일을 열어보았는데...
const rootReducer = combineReducers({
todos: todos,
});
const store = createStore(rootReducer);
그게 맞았다... reducer에서 객체로 todos의 키 : todos state를 가져오고 있었다....이 사실을 처음 알았다.
사실 이것은 문제가 아니지만 배운대로 그냥 사용하면서 reducer 구조 자체를 신경 안쓰고 있었다는 것이 좀 충격이었다.
2. 에러가 발생한 것은 다음 jsx문에서 { } 안에서 todos 배열을 불렀기 때문이었다.
return <> {todo} </>;
"개체는 React 하위 개체로 사용할 수 없습니다" 따라서 이 부분만 풀어서 출력해주면 해결됐다.
데이터 형식을 어떻게 짰을까 궁금해서 답안 소스코드를 보니 다음과 같이 객체 안에 키값을 주고 => todos와 todo를 따로 관리해 주었다.
const initialState = {
todos: [
{
id: "1",
title: "리액트",
body: "리액트를 배워봅시다",
isDone: false,
},
],
todo: {
id: "0",
title: "",
body: "",
isDone: false,
},
};
❗마치 JSON 데이터 형식을 보는 듯 했다. 만약 확장성을 고려하여 todos 외의 관련 데이터들도 같이 관리한다면 이렇게 더 많은 내용들을 관리할 수 있도록 객체로 한 번 더 감싸주면 좋을 것 같다.
Styled-components 리팩토링✅
어제 리팩토링 했던 부분이 만족스럽지 않아 다시 리팩토링 했다...
ButtonStyles.js 1차 리팩토링
export const buttonWidth = {
add: "200px",
};
export const buttonBgColor = {
delete: "#ccc",
done: "#64dc95",
notYet: "#6736ed94",
};
export const buttonHoverBgColor = {
delete: "#696969",
done: "#17d164",
notYet: "#6836ed",
};
css속성별로 해당하는 type에 맞게 객체 키값으로 접근하도록 하였다. 색상코드를 직접 관리하는게 유지보수도 어렵고 가독성에도 안좋다고 생각했다.
ButtonStyles.js 2차 리팩토링
// them.js 분리
export const colors = {
gray: "#696969",
lightGray: "#ccc",
green: "#17d164",
lightGreen: "#64dc95",
navy: "#38139efc",
lightNavy: "#6736ed94",
purple: "#a235fc",
lightPurple: "#bf79f8",
};
export const width = {
small: "200px",
};
//button
export const buttonBgColor = {
delete: colors.lightGray,
done: colors.lightGreen,
notYet: colors.lightNavy,
};
export const buttonHoverBgColor = {
delete: colors.gray,
done: colors.green,
notYet: colors.navy,
};
color값들을 따로 파일을 분리해 변수로 설정해 유지보수가 편하고 가독성이 훨씬 좋아졌다.
ButtonStyles.js 3차 리팩토링
export const buttonColors = {
delete: {
normal: colors.lightGray,
hover: colors.gray,
},
done: {
normal: colors.lightGreen,
hover: colors.green,
},
notYet: {
normal: colors.lightNavy,
hover: colors.navy,
},
};
버튼 type에 맞게 한 번에 color스타일을 관리할 수 있도록 리팩토링하였다. 훨씬 더 유지보수나 가독성이 좋아졌다. 여기서 추가적으로 border등이 추가되어도 키값만 추가하면 된다. 또 저 type들이 아닌 경우는 button에 직접 colors에 접근해 색상을 전달하면 바로 적용가능하도록 리팩토링 하였다.
'항해99 > 실전 WIL | TIL' 카테고리의 다른 글
[TIL-014] React Lv3과제 에러 디버깅 (0) | 2023.04.26 |
---|---|
[TIL-013] REST API란 무엇인가? (0) | 2023.04.25 |
[TIL-011] Styled-component 동적으로 활용하기, 기술 면접 스터디 발표 (0) | 2023.04.22 |
[TIL-010] 리액트 라우터(Router), 기술 매니저님 질문/응답 정리 (0) | 2023.04.21 |
[TIL-009] 리덕스(Redux)의 이해 및 활용 (0) | 2023.04.20 |