ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot/React] 카드 신청 페이지 제작
    Project/외국인 관광객을 위한 카드 플랫폼 2024. 8. 10. 23:03

    - 카드 신청 폼 만들기

    자료 참고 

    https://velog.io/@jiaegong/%EC%A3%BC%EB%AF%BC%EB%93%B1%EB%A1%9D%EB%B2%88%ED%98%B8-%EC%9E%90%EB%8F%99-%ED%95%98%EC%9D%B4%ED%94%88-%EB%84%A3%EA%B8%B0-%EB%92%B7%EC%9E%90%EB%A6%AC-%EB%A1%9C-%EB%A7%88%EC%8A%A4%ED%82%B9-%ED%95%98%EA%B8%B0

     

    주민등록번호 자동 하이픈 넣기, 뒷자리 *로 마스킹 하기

    가입 폼을 만들다보면 핸드폰 번호나 주민등록번호에 자동 하이픈이 생기게 해야 할 때가 있다. 열심히 해놨는데 기획 변경으로 이 부분을 다 날려야 하는 일이 생겨 필요한 코드만 정리해놓기

    velog.io

     

     

     

    카드 신청 프로세스 피그마 디자인

     

    - 문제 : 카드 신청할 때 입력된 카드 정보 데이터들 card 테이블에 insert하고 싶은데 단계별로 넣을 때마다 실시간으로 정보 하나씩 insert해서 db에 들어갔다가 나오는 과정으로 설계하려했지만 더 효율적인 방법이 있을 거 같아 고민

     

    - 해결: 리액트의 useContext사용해 프론트 단에서 데이터 모아서 마지막에 한꺼번에 입력시키고 백으로 insert하기로 함

     

     

    https://ko.react.dev/reference/react/useContext

     

    useContext – React

    The library for web and native user interfaces

    ko.react.dev

    useContext는 React의 훅(hook) 중 하나로, 컨텍스트(Context) 객체의 현재 값을 가져오기 위해 사용됩니다. 컨텍스트는 컴포넌트 트리 전체에 걸쳐 데이터를 전역적으로 전달할 수 있는 방법을 제공합니다. 이는 props를 통해 데이터를 전달해야 하는 필요성을 줄여줍니다

     

     


     

     

    1. Context 생성 및 제공

    import React, { createContext, useContext, useState } from 'react';
    
    const CardContext = createContext(); // 컨텍스트 객체를 생성
    
    //  useContext를 사용하여 CardContext의 현재 값을 반환
    export const useCardContext = () => {
        return useContext(CardContext);
    };
    
    export const CardProvider = ({children}) => {
        const [produceCardOffer, setProduceCardOffer] = useState({
            "card_id":"",
            "card_account":"",
            "card_balance" : "",
            "card_number":"",
            "card_password":"",
            "card_pickup":"",
            "card_status":"",
            "cvv_code":"",
            "expiration_date":"",
            "issue_date":"",
            "payment_bank":"",
            "payment_date":"",
            "pickup_date":"",
            "transportation":"",
            "card_type_id":"",
            "member_id":""
        });
    
        return (
            <CardContext.Provider value={{produceCardOffer, setProduceCardOffer}}>
                {children}
            </CardContext.Provider>
        )
    }

     

    • CardContext를 생성합니다.
    • useCardContext는 useContext를 사용하여 CardContext의 현재 값을 반환하는 커스텀 훅입니다.
    • CardProvider 컴포넌트는 produceCardOffer 상태와 그 상태를 업데이트하는 setProduceCardOffer 함수를 CardContext.Provider를 통해 하위 컴포넌트에 제공합니다.

     

     

     

    2. CardProvider로 Context 감싸기

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import { CardProvider } from './CardContext';
    
    ReactDOM.render(
        <CardProvider>
            <App />
        </CardProvider>,
        document.getElementById('root')
    );

     

    CardProvider로 App을 감싸서 CardContext를 앱 전체에 제공할 수 있도록 합니다.

     

     

     

     

    3. Context 사용하기 (예시: Card1 컴포넌트)

    import React, { useState, useEffect } from 'react';
    import '../../assets/Card.css';
    import Flickity from 'react-flickity-component';
    import axios from 'axios';
    import { useCardContext } from './CardContext';
    import { useNavigate } from 'react-router-dom';
    
    function Card1() {
        const [selectedCard, setSelectedCard] = useState(null);
        const [cards, setCards] = useState([]);
        const [isLoading, setIsLoading] = useState(true);
    
        const {produceCardOffer, setProduceCardOffer} = useCardContext();
    
        let navigate = useNavigate();
    
        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'>
    
                    <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={() => {
                    if(selectedCard) {
                        setProduceCardOffer(prevState => ({
                            ...prevState,
                            card_type_id:selectedCard.cardTypeId // 선택된 카드 타입 
                        }));
                        setTimeout(() => navigate('/card2'), 300);
                    }else{
                        console.log('카드가 선택되지 않았습니다.');
                    }
                     }}>신청하기</button>
                <div className='menubar'></div>
            </div>
        );
    }
    
    export default Card1;

     

    • Card1 컴포넌트에서 useCardContext를 사용하여 produceCardOffer와 setProduceCardOffer를 가져옵니다.
    • 사용자가 카드 신청 버튼을 클릭하면 selectedCard의 cardTypeId를 produceCardOffer 상태에 업데이트하고, 다음 페이지로 이동합니다.

     

    이와 같은 방식으로 다른 컴포넌트 (Card2, Card3, CardForm, Card5)에서도 useCardContext를 사용하여 produceCardOffer 상태를 가져오고 업데이트합니다. 각 컴포넌트는 필요에 따라 produceCardOffer의 특정 필드를 업데이트하고, 폼 제출 시 해당 데이터를 다음 단계로 전달합니다.

     

     

    4. 제출 

    import React from 'react';
    import { useCardContext } from './CardContext';
    function Card6(props) {
        const { produceCardOffer } = useCardContext();
        return (
            <div>
                <h3>카드 발급이 완료되었습니다.</h3>
                <pre>{JSON.stringify(produceCardOffer, null, 2)}</pre> {/* 데이터 확인 */}
            </div>
        );
    }
    
    export default Card6;

     

    • <pre> 태그 내에 produceCardOffer 객체를 JSON 형식으로 변환하여 출력합니다. JSON.stringify(produceCardOffer, null, 2)는 produceCardOffer 객체를 JSON 문자열로 변환하며, 두 번째 인자는 들여쓰기(indentation)를 위해 사용됩니다.
    • 이렇게 하면 produceCardOffer의 내용을 포맷팅된 JSON 형식으로 화면에 표시할 수 있습니다.

     

     

    카드 정보 다 선택 후 결과 화면

     

Designed by Tistory.