Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 유니티 #게임개발
- REACT
- 초기값 설정하기
- 알고리즘
- 에러해결방안
- 리액트
- styledcomonents
- Redux
- 혼자공부하는머신러닝딥러닝
- 백준 #코딩테스트 #코테 #알고리즘
- error맛집
- 백준 #코딩테스트
- axios
- 백준
- js
- 딥러닝
- CSS
- 혼공챌린지
- useEffect
- TS
- 타입스크립트
- clipboardapi
- 혼공단
- 구조분해할당
- 머신러닝
- 혼공머신
- reactmemo
- 코딩테스트
- 혼자공부하는머신러닝
- typeScript
Archives
- Today
- Total
좌충우돌 개발자의 길
[토이프로젝트] 리렌더링 왜 안되는거야? 본문
# 트러블 슈팅
초기 데이터로 bar chart가 잘 그려지는데 나중에 데이터가 추가적으로 입력되면 자동으로 차트에 반영되지 않는 현상이 발생했다.
# 해결 과정
## 원인분석
// 기존 코드
const dataset = useRecoilValue(datasetState);
const filterDataset = dataset.filter(
(value) => Number(value.year) === today.getFullYear()
);
// monthData에 값 더하기
filterDataset.map((value) => {
const month = Number(value.month)-1;
if (value.accountType === "Deposit") {
monthData[month].totalDeposit += Number(value.price);
} else {
monthData[month].totalWithdraw += Number(value.price);
}
}
);
1. 데이터 입력 즉시, 그래프가 반영되지 않는다? => 리렌더링이 되지 않았다!
=> useEffect를 사용해 리렌더링을 해보자!
## useEffect로 리렌더링 해보기
// 기존 데이터
const dataset = useRecoilValue(datasetState);
// 차트에 입력할 데이터
const monthData = [
{ month: "1", totalDeposit: 0, totalWithdraw: 0 },
{ month: "2", totalDeposit: 0, totalWithdraw: 0 },
{ month: "3", totalDeposit: 0, totalWithdraw: 0 },
{ month: "4", totalDeposit: 0, totalWithdraw: 0 },
{ month: "5", totalDeposit: 0, totalWithdraw: 0 },
{ month: "6", totalDeposit: 0, totalWithdraw: 0 },
{ month: "7", totalDeposit: 0, totalWithdraw: 0 },
{ month: "8", totalDeposit: 0, totalWithdraw: 0 },
{ month: "9", totalDeposit: 0, totalWithdraw: 0 },
{ month: "10", totalDeposit: 0, totalWithdraw: 0 },
{ month: "11", totalDeposit: 0, totalWithdraw: 0 },
{ month: "12", totalDeposit: 0, totalWithdraw: 0 },
];
useEffect(() => {
// 올해 연도의 데이터만 가져오기
const filterDataset = dataset.filter(
(value) => Number(value.year) === today.getFullYear()
);
// monthData에 값 더하기
filterDataset.map((value) => {
const month = Number(value.month)-1;
if (value.accountType === "Deposit") {
monthData[month].totalDeposit += Number(value.price);
} else {
monthData[month].totalWithdraw += Number(value.price);
}
});
}, [monthData]);
- 먼저, useEffect를 사용해서 monthData가 바뀔 때만 실행되도록 설정하였다.
- 하지만 여전히 되지 않았다... useEffect로만 사용하면 되지 않을 것 같아 비슷한 기능을 살펴봤다
- CreateAccountHistory.js 에서 입출금 거래 내역이 즉시 반영되었을 때는 useState함수를 써서 데이터값이 바뀌면 리렌더링 되게 만들었다.
=> useState를 사용해 리렌더링을 해보자!
## useState로 리렌더링 해보기
// 기존 데이터
const dataset = useRecoilValue(datasetState);
// 차트에 입력할 데이터
const [monthData, setMonthData] = useState([
{ month: "1", totalDeposit: 0, totalWithdraw: 0 },
{ month: "2", totalDeposit: 0, totalWithdraw: 0 },
{ month: "3", totalDeposit: 0, totalWithdraw: 0 },
{ month: "4", totalDeposit: 0, totalWithdraw: 0 },
{ month: "5", totalDeposit: 0, totalWithdraw: 0 },
{ month: "6", totalDeposit: 0, totalWithdraw: 0 },
{ month: "7", totalDeposit: 0, totalWithdraw: 0 },
{ month: "8", totalDeposit: 0, totalWithdraw: 0 },
{ month: "9", totalDeposit: 0, totalWithdraw: 0 },
{ month: "10", totalDeposit: 0, totalWithdraw: 0 },
{ month: "11", totalDeposit: 0, totalWithdraw: 0 },
{ month: "12", totalDeposit: 0, totalWithdraw: 0 },
]);
useEffect(() => {
// 올해 연도의 데이터만 가져오기
const filterDataset = dataset.filter(
(value) => Number(value.year) === today.getFullYear()
);
// monthData에 값 더하기
filterDataset.map((value) => {
const month = Number(value.month)-1;
if (value.accountType === "Deposit") {
const findIndex = monthData.findIndex(element => element.code == month);
let copyArray = [...monthData];
if(findIndex != -1) {
const totalDeposit = month[findIndex].totalDeposit + Number(value.price);
copyArray[findIndex] = {...copyArray[findIndex], totalDeposit: totalDeposit};
}
} else {
// if문 코드와 비슷
...
}
});
}, [monthData]);
- monthData를 useState를 적용해서 구현했다.
- 하지만.... 이 역시 안됐다. 분명 잘 monthData값에 새로운 데이터로 들어갔는데 리렌더링이 되지 않았다.
- 난 이쯤에서 리렌더링이 되는 조건에 대해서 다시 조사를 시작했다.
## 리렌더링 되는 조건
- 컴포넌트 자신의 state가 변하기
- 부모 컴포넌트로부터 받는 props가 변하기
- 부모 컴포넌트가 리렌더링 되기
- 난 useState만 리렌더링하게 만들 수 있다고 생각했는데 아니었다!! 그래서 가장 적합한 2번으로 리렌더링을 시도해봤다.
## 부모 컴포넌트로부터 받는 props가 변하기
// Main.js
const dataset = useRecoilValue(datasetState);
return (
<Wrapper>
<Title />
<Alarm />
<Total />
<GraphAccount dataset={dataset} /> // dataset을 부모 컴포넌트에서 props로 전달해주기
...
</Wrapper>
);
// GraphAccount.js
function GraphAccount({dataset}) {
const today = new Date(); // 오늘 날짜
// 차트에 입력할 데이터
const monthData = [
{ month: "1", totalDeposit: 0, totalWithdraw: 0 },
{ month: "2", totalDeposit: 0, totalWithdraw: 0 },
{ month: "3", totalDeposit: 0, totalWithdraw: 0 },
{ month: "4", totalDeposit: 0, totalWithdraw: 0 },
{ month: "5", totalDeposit: 0, totalWithdraw: 0 },
{ month: "6", totalDeposit: 0, totalWithdraw: 0 },
{ month: "7", totalDeposit: 0, totalWithdraw: 0 },
{ month: "8", totalDeposit: 0, totalWithdraw: 0 },
{ month: "9", totalDeposit: 0, totalWithdraw: 0 },
{ month: "10", totalDeposit: 0, totalWithdraw: 0 },
{ month: "11", totalDeposit: 0, totalWithdraw: 0 },
{ month: "12", totalDeposit: 0, totalWithdraw: 0 },
];
useEffect(() => {
// 올해 연도의 데이터만 가져오기
const filterDataset = dataset.filter(
(value) => Number(value.year) === today.getFullYear()
);
// monthData에 값 더하기
filterDataset.map((value) => {
const month = Number(value.month) - 1;
if (value.accountType === "Deposit") {
monthData[month].totalDeposit += Number(value.price);
} else {
monthData[month].totalWithdraw += Number(value.price);
}
});
}, [monthData]);
- 성공했다! 리렌더링이 제대로 이루어지지 않아 차트에 바로 입력된 값이 반영되지 않았던 것이다.
'PROJECTS > Simple Wallet : 심플한 가계부' 카테고리의 다른 글
[토이프로젝트] 백엔드 서버 없이 DB 연결하기 (0) | 2022.11.22 |
---|---|
[토이프로젝트] Styled-Component에서 구글 폰트 사용하기 (0) | 2022.11.17 |
[토이프로젝트] jsx에서 else if문 사용하는 방법 (0) | 2022.11.15 |
[토이프로젝트] useState를 이용해 기존 배열에 값 추가하기 (0) | 2022.11.14 |
[토이프로젝트] input 입력 시 한글자만 입력되고 더이상 입력되지 않는 에러가 발생 (0) | 2022.11.14 |