Jun's Blog

미니샵 홈페이지 만들어보기(with React Bootstrap) - (1) 본문

WEB/React

미니샵 홈페이지 만들어보기(with React Bootstrap) - (1)

luckydadit 2025. 2. 11. 12:17

1. 기본 구조 만들기

 

신규 폴더 생성 : coffee_bread_shop, components

 

신규 파일 생성 : Bottom.js, Content.js, Top.js, App.css, App.js

 

Top.js 파일 내용
function App(){
    console.log('Top');


    return(
        <>
            Top
        </>
    );
}

export default App;
 Content.js 파일 내용
function App(){
    console.log('Content');


    return(
        <>
            Content
        </>
    );
}

export default App;
Bottom.js 파일 내용
function App(){
    console.log('Bottom');


    return(
        <>
            Bottom
        </>
    );
}

export default App;
App.js 파일 내용
import './App.css';

// import 앱이름 from './components/파일이름';
import Content from './components/Content';
import Top from './components/Top';
import Bottom from './components/Bottom';


function App(){
    console.log('미니샵 실습');


    return(
        <>
            <Top /><br/><br/><br/><br/>
            <Content /><br/><br/><br/><br/>
            <Bottom />
        </>
    );
}

export default App;

 

App.js 파일 내용
*{
    margin:10px;
}

 

 

<실행결과>

 

2. 상단, 중단, 하단 부분 만들어보기(with props)

 

2.1 상단(Top) 만들어보기

 

<실행결과>

 

2.2 하단(Bottom) 만들어보기

 

<실행결과>

 

2.3 React Bootstrap 설치

https://react-bootstrap.github.io/docs/components/alerts

 

Alerts | React Bootstrap

Provide contextual feedback messages for typical user actions with the handful of available and flexible alert messages.

react-bootstrap.netlify.app

 

2.3.1 reactapp을 설치하 경로에 가서 bootstrap 라이브러리 설치

npm install bootstrap react-bootstrap 실행



2.3.2 src/index.js 또는 App.js 파일에 다음 스타일을 추가해 줍니다.
import 'bootstrap/dist/css/bootstrap.min.css'; 를 추가함.(index.js에 추가하면 모두 적용됨)

 

2.3.4 전체 구조를 React Bootstrap 적용하기 

 

 

<실행결과>

2.3.5 Bottom Button 생성하기

 

 

 

2.4 중단(content) 만들어보기

import { useState } from 'react'; // 추가
    const [products] = useState([
        {id:1, name:"프렌치 바게트", price:1000, category:'bread', stock:111, image:'french_baguette_01.png', description:"프랑스의 대표적인 빵 중 하나로, 길쭉하고 얇은 형태의 식빵입니다. 바삭하면서도 촉촉한 식감과 진한 맛이 특징입니다."},
        {id:2, name:"크로와상", price:2000, category:'bread', stock:222, image:'croissant_02.png', description:"프랑스의 대표적인 베이커리 중 하나로, 층층이 쌓인 반죽에 버터를 추가하여 구워낸 과자입니다."},
        {id:3, name:"아메리카노", price:3000, category:'beverage', stock:333, image:'americano01.png', description:"에스프레소의 쓴 맛과 향을 좋아하는 사람들이 물을 추가해서 즐기는 음료로, 물과 에스프레소의 비율에 따라서 쓴 맛과 진하게 즐길 수 있습니다."},
        {id:4, name:"카푸치노", price:4000, category:'beverage', stock:444, image:'cappuccino01.png', description:"스팀밀크와 거품을 올린 것을 섞어 만든 이탈리아의 전통적인 커피 음료입니다."}    
    ]);

 

 

 

 

import Table from 'react-bootstrap/Table';

function App(props) {
    //console.log('Content');

    var contents = props.contents; // 상품 여러개를 가지고 있는 배열
    console.log(contents);

function getProductList(item, index){
    const trTag =
        <tr key={index}>
            <td align='center'>{item.name}</td>
                <td align='right'>{Number(item.price).toLocaleString()}</td>
                <td align='center'>{item.category === 'bread' ? '빵' : '음료수'}</td>
        </tr>
    ;
    return trTag;
}

    const ProductList = () => {
        const dataList = contents.map(getProductList);
        return <tbody>{dataList}</tbody>
    }

    return (
        <>
            <Table striped bordered hover>
                <thead>
                    <tr>
                        <th>상품명</th>
                        <th>가격</th>
                        <th>카테고리</th>
                    </tr>
                </thead>
                    {ProductList()}
            </Table>
        </>
    );
}

export default App;

 

<실행결과>

 

App.js 소스 파일
import './App.css';
import Card from 'react-bootstrap/Card';

// import 앱이름 from './components/파일이름';
import Content from './components/Content';
import Top from './components/Top';
import Bottom from './components/Bottom';
import { useState } from 'react';


function App() {
    //console.log('미니샵 실습');
    const title = '커피&베이커리 샵';
    const comment = '어서오세요~ 다양한 빵과 음료수가 있습니다.';
    const message = 'Have a GoodDay! 좋은 하루되세요.'

    const [products] = useState([
        {id:1, name:"프렌치 바게트", price:1000, category:'bread', stock:111, image:'french_baguette_01.png', description:"프랑스의 대표적인 빵 중 하나로, 길쭉하고 얇은 형태의 식빵입니다. 바삭하면서도 촉촉한 식감과 진한 맛이 특징입니다."},
        {id:2, name:"크로와상", price:2000, category:'bread', stock:222, image:'croissant_02.png', description:"프랑스의 대표적인 베이커리 중 하나로, 층층이 쌓인 반죽에 버터를 추가하여 구워낸 과자입니다."},
        {id:3, name:"아메리카노", price:3000, category:'beverage', stock:333, image:'americano01.png', description:"에스프레소의 쓴 맛과 향을 좋아하는 사람들이 물을 추가해서 즐기는 음료로, 물과 에스프레소의 비율에 따라서 쓴 맛과 진하게 즐길 수 있습니다."},
        {id:4, name:"카푸치노", price:4000, category:'beverage', stock:444, image:'cappuccino01.png', description:"스팀밀크와 거품을 올린 것을 섞어 만든 이탈리아의 전통적인 커피 음료입니다."}    
    ]);


    return (
        <Card>
            <Card.Header>
                <Top title={title} comment={comment} />
            </Card.Header>
            <Card.Body>
                <Content contents={products} />
            </Card.Body>
            <Card.Footer>
                <Bottom message={message} />
            </Card.Footer>
        </Card>

    );
}

export default App;