1. db연결하기
firebase에서 데이터를 가지고 오면서 해당 데이터를 최신으로 정렬하고 새로 작성하는 item의 id에 +1이 되도록 설정했다.
useEffect(() => {
const localData = collection(db, "health");
if (localData) {
const recordList = JSON.parse(localData).sort(
(a, b) => parseInt(b.id) - parseInt(a.id)
);
if (recordList.length >= 1) {
dataId.current = parseInt(recordList[0].hid + 1);
dispatch({ type: "INIT", data: recordList });
}
}
}, []);
이렇게 했을 때, 아래와 같은 에러가 발생했다.
"[object Object]" is not valid JSON
SyntaxError: "[object Object]" is not valid JSON
JSON.parse는 문자열을 json 객체로 변환시키는 것인데, 여기서 localData는 firebase 컬렉션 객체이기에 오류가 난다.
그래서 firebase에서 getDocs함수를 사용해 데이터를 가져와야한다.
//✅컴포넌트가 마운트 되었을 때 firebase에서 데이터 가져오기
useEffect(() => {
const fetchData = async () => {
// firebase에서 데이터를 가져와서 해당 데이터를 records 변수에 저장한다
const querySnapshot = await getDocs(collection(db, "health"));
const records = querySnapshot.docs.map((doc) => doc.data());
// 데이터 최신으로 정렬
const recordList = records.sort(
(a, b) => parseInt(b.hid) - parseInt(a.hid)
);
// 데이터가 있다면 새로 작성하는 데이터의 id가 +1 되도록
if (recordList.length >= 1) {
dataId.current = parseInt(recordList[0].hid + 1);
dispatch({ type: "INIT", data: recordList });
}
};
fetchData(); //함수 호출
}, []);
querySnapshot과 records를 콘솔에 찍었을 때 아래와 같이 출력된다.

2. 데이터 출력
받아온 데이터를 출력해야하는데 데이터를 받아오기전 먼저 출력되는 비동기적 작동때문에 출력하지 못하는 에러가 있었다.
Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of undefined (reading 'map')
이때는 두가지 해결방법이 있다.
1. 조건부 렌더링으로 데이터가 없으면 Loading 컴포넌트 있으면 제대로 출력하도록
2. useEffect를 사용하여 데이터가 변경될 때 실행되도록
if (!data) {
return (
<div>
<Loading />
</div>
);
}
첫번째 조건부 렌더링을 위와 같이 사용하였는데 실행되지 않았다.
이유는 위에서 data의 초기값으로 빈배열([ ])로 줬는데, 빈 배열은 undefind나 null로 인식하지 않기 때문에 로딩컴포넌트가 뜨지 않았다.
그래서
if (data.length >= 1) {
가 아니고, 정상출력인줄 알았으나 새로고침 시 바로 출력되지 않고, 다른 탭으로 이동 후 다시 돌아올 때만 제대로 출력되는 에러가 있었다.
useEffect에 마운트될 때만 setData를 실행하도록 했는데, healthData가 변경될 때마다 setData가 실행되도록 변경했더니 오류없이 정상작동 했다.
useEffect(() => {
if (healthData.length >= 1) {
setData(healthData);
}
}, [healthData]);

그래서 조건부 렌더링을 추가하여 데이터를 받기 전에는 아예 로딩 컴포넌트가 출력되도록 바꾸었다.
로딩컴포넌트는 추후 수정 예정

3. 테이블 출력

데이터를 테이블에 맞게 출력해야하는데 위와 같이 하나의 열에 모든 데이터들이 들어가게 출력되었다.
테이블 열에 맞게 데이터가 출력하려면 어떻게 해야할까?
HealthItem 컴포넌트에서 리턴문을 div로 묶고 그 안에 tr 태그를 넣었는데, div를 없애고 리턴을 tr 태그 자체로 받으니까 아래와 같이 열에 맞게 출력되었다.

'TIL' 카테고리의 다른 글
| 231231_TIL : react-native 시작하기 (0) | 2023.12.31 |
|---|---|
| 231223_TIL : 슬라이더 라이브러리 react-slick 사용하기 (1) | 2023.12.24 |
| 231221_TIL : 리액트 성능 향상 - batching, useTransition, useDeferredValue (0) | 2023.12.21 |
| 231220_TIL : 리액트 페이지 이동, 함수 호출과 참조 전달, lazy 문법 (1) | 2023.12.20 |
| 231201_TIL : 리덕스 툴킷(Redux-toolkit)으로 상태관리하여 로그인 구현하기 (0) | 2023.12.01 |