ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot/React] 카드 CRUD 연동해 카드 슬라이드 UI 제작
    Project/외국인 관광객을 위한 카드 플랫폼 2024. 8. 7. 20:01

    - 카드, 카드유형, 결제 테이블 전체 crud 제작

     

    문제

    - 카드 슬라이드 배너 제작 중 db 데이터는 넘어오는데 화면에 안보여짐

    아래가 문제 코드

    import React, { useState, useEffect } from 'react';
    import './Card.css';
    import Flickity from 'react-flickity-component';
    import axios from 'axios';
    
    function Card() {
        const [selectedCard, setSelectedCard] = useState(null);
        const [cards, setCards] = useState([]);
    
        const flickityOptions = {
            cellAlign: 'right',
            pageDots: false,
            groupCells: '20%',
            selectedAttraction: 0.03,
            friction: 0.15,
        };
    
        useEffect(() => {
            axios.get('/api/cards')
                .then(response => {
                    console.log('Fetched cards:', response.data);
                    setCards(response.data);
                    if (response.data.length > 0) {
                        setSelectedCard(response.data[0]); 
                    }
                })
                .catch(error => {
                    console.error('There was an error fetching the cards!', error);
                });
        }, []);
    
        const handleChange = (index) => {
            console.log("인덱스", index);
            console.log("이거왜안뜸",cards[index]);
            setSelectedCard(cards[index]);
        };
    
        return (
            <div className='container'>
                <div className='header'>
                    카드 신청
                </div>
    
                <div className='content'>
                    <ul className="progressbar">
                        <li className="complete"></li>
                        <li className="complete"></li>
                        <li className="active"></li>
                        <li className="half-complete"></li>
                    </ul>
    
                    <div className='carousel-container'>
                        <Flickity
                            className='carousel'
                            options={flickityOptions}
                            flickityRef={(c) => {
                                if (c) {
                                    c.on('change', (index) => handleChange(index));
                                }
                            }}
                        >
                            {cards.map((card) => (
                                <div className="carousel-cell" key={card.cardTypeId}>
                                    <img src={card.cardImg} className="p" alt={card.cardName} />
                                </div>
                            ))}
                        </Flickity>
                    </div>
    
                    {selectedCard && (
                        <div className='selected-card'>
                            <div>카드이름: {selectedCard.cardName}</div>
                            <div>카드사용목적: {selectedCard.cardUsage}</div>
                            <div>카드한도: {selectedCard.cardLimit}</div>
                            <div>연회비: {selectedCard.annualFee}</div>
                        </div>
                    )}
                </div>
    
                <div className='menubar'></div>
            </div>
        );
    }
    
    export default Card;

     

    문제해결

    import React, { useState, useEffect } from 'react';
    import '../../assets/Card.css';
    import Flickity from 'react-flickity-component';
    import axios from 'axios';
    
    function Card() {
        const [selectedCard, setSelectedCard] = useState(null);
        const [cards, setCards] = useState([]);
        const [isLoading, setIsLoading] = useState(true);
    
        const flickityOptions = {
            cellAlign: 'right',
            pageDots: false,
            groupCells: '20%',
            selectedAttraction: 0.03,
            friction: 0.15,
        };
    
        useEffect(() => {
            axios.get('/api/cards')
                .then(response => {
                    // console.log('Fetched cards:', response.data);
                    setCards(response.data);
                    if (response.data.length > 0) {
                        setSelectedCard(response.data[0]);
                    }
                    setIsLoading(false);  // 데이터 로드 완료
                })
                .catch(error => {
                    console.error('There was an error fetching the cards!', error);
                    setIsLoading(false);  // 데이터 로드 실패
                });
        }, []);
    
        const handleChange = (index) => {
            if (cards.length > 0 && index < cards.length) {
                setSelectedCard(cards[index]);
                // console.log('Selected card:', cards[index]);
            } else {
                console.log("카드 데이터가 아직 로드되지 않았습니다.");
            }
        };
    
        return (
            <div className='container'>
                <div className='header'>
                    <div>카드 신청</div>
                </div>
    
                <div className='content'>
                    <ul className="progressbar">
                        <li className="complete"></li>
                        <li className="complete"></li>
                        <li className="active"></li>
                        <li className="half-complete"></li>
                    </ul>
    
                    <div className='carousel-container'>
                        {isLoading ? (
                            <div>카드 불러오는 중...</div>
                        ) : (
                            <Flickity
                                className='carousel'
                                options={flickityOptions}
                                flickityRef={(c) => {
                                    if (c) {
                                        c.on('change', (index) => handleChange(index));
                                    }
                                }}
                            >
                                {cards.map((card, index) => (
                                    <div className="carousel-cell" key={card.cardTypeId}>
                                        <img src={card.cardImg} className="p" alt={card.cardName} />
                                        <div className='card-info'>
                                            <div>카드이름: {card.cardName}</div>
                                            <div>카드사용목적: {card.cardUsage}</div>
                                            <div>카드한도: {card.cardLimit}</div>
                                            <div>연회비: {card.annualFee}</div>
                                        </div>
                                    </div>
                                ))}
                            </Flickity>
                        )}
                    </div>
    
                    {selectedCard && (
                        <div className='selected-card'>
                            <div>선택한 카드이름: {selectedCard.cardName}</div>
                            <div>카드사용목적: {selectedCard.cardUsage}</div>
                            <div>카드한도: {selectedCard.cardLimit}</div>
                            <div>연회비: {selectedCard.annualFee}</div>
                        </div>
                    )}
                </div>
                
                <button onClick={() => { console.log('선택한 카드이름:', selectedCard ? selectedCard.cardName : '카드가 선택되지 않았습니다') }}>신청하기</button>
                <div className='menubar'></div>
            </div>
        );
    }
    
    export default Card;

     

    문제는 상태 업데이트와 Flickity의 on 이벤트 간의 비동기성 문제일 가능성이 큽니다. handleChange 함수가 실행될 때 cards 배열이 이미 로드된 상태인지 확인해야 합니다. 또한, cards 배열이 비어 있지 않다는 것을 다시 확인하는 것도 중요합니다.

    아래 수정된 코드에서, handleChange 함수가 실행될 때 cards 배열이 이미 로드된 상태인지 명확하게 확인하고, cards 배열을 로드 중일 때는 로딩 메시지를 표시하도록 했습니다.

    -------------

    문제는 아마도 비동기 상태 업데이트와 초기 로딩 상태를 명확하게 관리하지 않았기 때문입니다. isLoading 상태를 추가하여 데이터 로드 중일 때와 로드 완료 후를 명확히 구분함으로써 문제가 해결되었습니다.

    구체적으로 다음과 같은 문제들이 있었을 수 있습니다:

    1. 초기 상태 관리 부족: cards 배열이 비어 있을 때 handleChange 함수가 실행되었을 때 카드 데이터를 제대로 처리하지 못함.
    2. 비동기 작업 완료 후 상태 업데이트: 데이터가 로드되기 전에 handleChange가 실행되면 빈 배열에 접근하려고 했던 문제.
    3. 사용자 경험 향상: 로딩 중이라는 상태를 명확히 표시하지 않아서 사용자에게 혼란을 줄 수 있었음.

    이러한 문제를 해결하기 위해 isLoading 상태를 추가하여 데이터 로딩 상태를 명확히 관리했습니다.

    최종적으로 수정된 코드 요약:

    1. isLoading 상태 추가: 데이터 로드 중 상태를 관리하기 위해 추가했습니다.
    2. 로딩 상태 처리: 데이터가 로드 중일 때 사용자에게 로딩 중임을 알리는 메시지를 표시했습니다.
    3. 상태 업데이트 후 렌더링: 데이터 로드가 완료된 후에만 Flickity 슬라이더와 선택된 카드 정보를 표시하도록 했습니다.

    이로 인해 초기 로딩 상태와 비동기 상태 업데이트가 명확하게 구분되어 문제가 해결되었습니다.

     

Designed by Tistory.