

지난번 기능구현 이후로 스탠다드반 수업을 통해 context api, redux 를 이용해서 전역관리 하는 법에 대해 복습을 했다. 개인과제할때 도움이 되는 스탠다드 과제도 내주셔서 그거 먼저 풀면서 연습을 하고 개인과제에 비슷하게 활용했다.
확실히 실시간 수업을 통해 지난번 개념 복습 + 과제로 한번 더 복습하니 훨-씬 도움이 많이 된다. 특히 개인과제에 접목시킬때 예전엔 어떻게할지 감도 안잡혔었는데 todolist 과제때부터 가계부 과제까지 리액트 훅에대해 전체적인 개념이 잡힌 느낌이다.
✅ react-router-dom 을 활용한 페이지 이동처리
✅ styled-component 를 이용한 스타일링 적용
✅ context api 를 이용한 전역 상태 관리
✅ redux 를 이용한 전역 상태 관리
props-drilling 으로 기능구현하는 부분이 생각보다 오래걸렸고, 오히려 전역상태 관리하는 브랜치로 리팩토링을 생각보다 빠르게했다.
Detail 페이지에서 로컬스토리지에 접근하여 데이터를 수정하는 부분을 useRef 로 사용해보느라 개념이 생소했지만, state 보다 current 로 참조해서 접근하는부분이 훨씬 단순하다고 느꼈다.
과제를 하면서 리렌더링을 최대한 적게하는 법이 뭘까, 어떤데이터를 보관?유지?? 시켜놔야 효율적일까를 항상 고민하고 있다.-> 이 부분이 해결되면 코드도 훨!씬! 간결해진다는걸 배웠다..!!
다만.. 마지막에 Redux 브랜치까지 마무리한 후, Nivo - pie chart 로 지출 요약 그래프를 첨부하려고 했는데 스타일링에 막히는 부분이 있어서 마지막 시간까지 탈탈 털어서 해결했다.....
그래도 .. 마지막에 스타일링 하기위해 기능구현 하는것도 있으니까... 애써 멘탈 잡고 ㅎ 라이브러리 설치가 안되는거때문에 못하는건 너무 억울해서 될때까지 했다.
차트 정보는 왤케 없는지!! (*노트북 재부팅후 좀 냅두다가 다시 vscode 관리자모드로 실행하고 라이브러리 설치하니까 잘되더라...)
Nivo는 자주 쓸거 같으니 따로 포스팅을 해야겠다. 결과물을 보니 너무 만족스러운 그래프라 오류 해결하고나니까 너~무 행복하다.
아직은 useContext 와 Redux 를 언제 어떤 데이터를 분리해서 사용해야되는지 감이 잘 안온다ㅜㅠ 다음 팀플때는 일부러 기능을 나눠서 적용시켜보고싶다. 예를들어 다크모드/라이트모드엔 context 를 사용한다던지..!!


// DataContext.jsx
import React, { createContext } from "react";
import { useState } from "react";
export const DataContext = createContext();
export const DataProvider = ({ children }) => {
const [activeIndex, setActiveIndex] = useState("");
const [data, setData] = useState([]);
return (
<DataContext.Provider
value={{ activeIndex, setActiveIndex, data, setData }}
>
{children}
</DataContext.Provider>
);
};
[Question] 🤔 몇번 안쓰이는 (activeIndex : 클릭된 버튼)도 전역상태에서 관리하는게 맞나요??
// Header.jsx const Header = ({ title }) => { return ( <StHeader> <StTitle>{title}</StTitle> <StIcon src={Icon} alt="Icon" /> </StHeader> ); }; // Detail.jsx return(<Header title="Modify expenditure" />) // Home.jsx return(<Header title="MONEY RECORD" />)
// 수정한 코드 import { createSlice } from "@reduxjs/toolkit"; const initialState = { activeIndex: "", data: JSON.parse(localStorage.getItem("localData")) || [], }; const dataSlice = createSlice({ name: "data", initialState, reducers: { setActiveIndex: (state, action) => { state.activeIndex = action.payload; }, setData: (state, action) => { state.data = action.payload; localStorage.setItem("localData", JSON.stringify(action.payload)); }, modifyData: (state, action) => { const { id, date, category, price, description } = action.payload; const updatedData = state.data.map((item) => item.id === id ? { id, date, category, price, description } : item ); state.data = updatedData; localStorage.setItem("localData", JSON.stringify(updatedData)); }, deleteData: (state, action) => { const id = action.payload; const deletedData = state.data.filter((item) => item.id !== id); state.data = deletedData; localStorage.setItem("localData", JSON.stringify(deletedData)); }, }, }); export const { setActiveIndex, setData, modifyData, deleteData } = dataSlice.actions; export default dataSlice.reducer;
기능구현을 우선으로 하고 스타일링을 할 생각이었어서 차트삽입이나 헤더부분을 나중에 구현했다.
Redux 가 최종 브랜치가 되었는데, context 랑 props-drilling 브랜치에는 스타일링 적용이 하나도 안된게 너무 아쉬웠다. merge를 하기엔 기능 부분을 구현한 코드도 함께 있어서 뭔가 충돌이 많이 발생할듯해서 그대로 제출했고, 튜터님께 아래와 같은 질문을 남겼다!
[Question] 🤔 스타일드 컴포넌트를 사용해서 CSS 부분을 jsx 하나의 파일에서 관리하면, 스타일링만 변화시켰는데도 merge 할때 충돌나는 경우가 많나요?! 스타일 변경만 하는 브랜치를 따로 처음에 만들었어야되는건가 하는 생각이 듭니다..!
지난번 과제때 튜터님께 css 파일 분리에 대해 여쭤보았을때 styled-components 를 추천해주신게 이해가 됐다. 하나의 파일 안에서 관리할 수 있어서 폴더구조도 훨씬 깔끔했고, 직관적이라 해당 부분의 스타일을 쉽게 수정할 수 있었다. 또한 헤더의 경우 컴포넌트화를 통해 detail 컴포넌트에서도 똑같이 사용할 수 있어서 정말 편했다! 스타일드 컴포넌트를 통해 동적으로 스타일을 다르게 적용하는 부분도 코드가 한결 짧아져서 좋았다.
다만, 아직은 일반 컴포넌트인지 스타일드 컴포넌트인지 헷갈리므로 컴포넌트 이름 앞에 St 를 붙이는게 훨씬 편하다.
useState 는 input 같이 제어 컴포넌트로 바로 상태를 관리할 때 쓰면 좋은거 같고, useRef 는 current 로 값을 보관할 수 있으니까 데이터를 모아서 한번에 업데이트(리렌더링) 시킬 때 사용하기 좋은 것 같다. 훅 사용시 import 가 자동으로 안되는 경우가 많으니 꼭꼭 신경써야겠다고 느꼈다.
5번 이상은 까먹고 콘솔에 찍힌 에러 보고 알았다ㅜㅜ
상황에 맞게 훅과 리덕스를 적용하기가 아직은 익숙하지 않지만, 하다보면 익숙해지겠지 ㅎㅎ
팀프로젝트에서 다양하게 연습해보자!🤠