yamoo9 / likelion-FEQA

질문/답변 — 프론트엔드 스쿨, 멋사
29 stars 9 forks source link

[LAB-15] Firestore에서 받은 정보를 저장한 배열이 렌더링되지 않습니다.(이미지) #210

Closed ovelute53 closed 1 year ago

ovelute53 commented 1 year ago

질문 작성자

윤새한

문제 상황

export const Reservation3 = () => {
  // const [imageUrl, setImageUrl] = useState('');
  const [rooms, setRooms] = useState([]);
  const [roomImageList, setRoomImageList] = useState([]);

  useLayoutEffect(() => {
    const getRooms = (async () => {
      const q = query(
        collection(db, 'rooms'),
        where('maxNumberOfPerson', '<=', 5)
      );

      const querySnapshot = await getDocs(q);
      if (querySnapshot.empty) {
        console.log('다른 날짜를 선택해주세요');
      } else {
        const roomList = [];
        const imageList = [];
        querySnapshot.forEach((doc) => {
          const storage = getStorage();
          const storageRef = ref(storage, doc.data().imageUrl);
          getDownloadURL(storageRef)
            .then((url) => {
              imageList.push(url);
            })
            .catch((error) => {
              console.error(error);
            });

          roomList.push(doc.data());
        });
        setRooms(roomList);
        setRoomImageList(imageList);
      }
    })();
  }, []);

  return (
    <ReservationTitle value={'객실'}>
      <StepNavigation
        page={'reservation3'}
        labelArray={['투숙객 선택', '날짜 선택', '객실 선택']}
      ></StepNavigation>
      <Container>
        {rooms.map((room, index) => (
          <RoomInfoCard
            key={room.id}
            name={room.name}
            description={room.description}
            notice={room.notice}
            addInfoSite={room.site}
            price={room.price}
            imageUrl={roomImageList[0]}
            isLast={index === rooms.length - 1}
          />
        ))}
      </Container>
      <ButtonWrapper>
        <BackButton id={'reservation2'} value={'뒤로'} />
        <ContinueButton id={'reservation4'} value={'장바구니 및 결제'} />
      </ButtonWrapper>
    </ReservationTitle>
  );
};

export default Reservation3;

렌더링된 화면

image

.env파일을 디엠으로 보내드리겠습니다.

프로젝트 저장소 URL

https://github.com/ovelute53/final-project/blob/develop/final-cra/src/pages/Reservation3.jsx

develop 브랜치에서 작업 진행하였습니다.

환경 정보

yamoo9 commented 1 year ago

문제 해결

질문의 문제는 https://github.com/yamoo9/likelion-FEQA/issues/208#issuecomment-1480903863 답변과 유사한 상황입니다. Reservation3.jsx 파일을 아래와 같이 수정해보세요. 😊

Reservation3.jsx

export const Reservation3 = () => {
  const [rooms, setRooms] = useState([]);

  useLayoutEffect(() => {
    (async () => {
      const q = query(
        collection(db, 'rooms'),
        where('maxNumberOfPerson', '<=', 5)
      );

      const querySnapshot = await getDocs(q);

      if (querySnapshot.empty) {
        console.log('다른 날짜를 선택해주세요');
      } else {
        const roomList = [];
        const imageList = [];

        querySnapshot.forEach((doc) => {
          const storage = getStorage();

          const data = doc.data();
          roomList.push(data);

          const storageRef = ref(storage, data.imageUrl);
          imageList.push(
            getDownloadURL(storageRef)
              .then((url) => url)
              .catch((error) => console.error)
          );
        });

        Promise.all(imageList)
          .then((imageUrls) => {
            imageUrls.forEach((url, index) => {
              roomList[index].imageUrl = url;
            });
            setRooms(roomList);
          })
          .catch((error) => console.error);
      }
    })();
  }, []);

  return (
    <ReservationTitle value={'객실'}>
      <StepNavigation
        page={'reservation3'}
        labelArray={['투숙객 선택', '날짜 선택', '객실 선택']}
      ></StepNavigation>
      <Container>
        {rooms.map((room, index) => (
          <RoomInfoCard
            key={room.id}
            name={room.name}
            description={room.description}
            notice={room.notice}
            addInfoSite={room.site}
            price={room.price}
            imageUrl={room.imageUrl}
            isLast={index === rooms.length - 1}
          />
        ))}
      </Container>
      <ButtonWrapper>
        <BackButton id={'reservation2'} value={'뒤로'} />
        <ContinueButton id={'reservation4'} value={'장바구니 및 결제'} />
      </ButtonWrapper>
    </ReservationTitle>
  );
};

그러면 아래처럼 이미지가 정상적으로 표시됩니다.