본문 바로가기
React TIL

[React] Day_8 맨땅에 헤딩하는 실습일기 Part 2 - (2)

by 림졍 2024. 9. 7.

 

어서와, 응용편은 처음이지?

 

열분 안녕하세요. 다시 돌아온 림졍입니다. 🙋🏻‍♀️

오늘은 지난 시간에 작성했던 렌더링 응용 편으로 돌아왔습니다.

(복잡하게 부르기 싫으니 편하게 2탄으로 부를게요.🙄)

응용 편은 뭐.. 별건 없고요..

지난 시간에 진행했던 내용에 추가적인 기능을 넣어 구현해 보는 거니

부담 갖지 말고 읽어주시길 바라겠습니다..!

(지난 게시글과 이어지니, 잘 모르겠다 싶으신 분들은 바로가기를 눌러주세요.)

레쯔고.

 

 

맛보기 - 작성에 앞서.. 결과물부터 보시죠.

 

어때요, 제법 메뉴판 같죠?

 

결과물을 간단하게 정리하자면..

우리가 제작한 렌더링 화면에 버튼을 추가하여

버튼을 누르면 메뉴판에 해당되는 메뉴만 볼 수 있게끔 만들고,

다시 전체 메뉴를 보고 싶으면 [전체 메뉴] 를 눌러 초기화를 시킬 수 있도록 제작할 예정이다.

자, 이제 어떻게 만들어지는 것인지 밑에서 슬슬 알아보도록 하자.

 

 

렌더링 응용 0단계 - 객체 속성 추가하기

본격적인 내용에 앞서, 퀘스트의 선택사항을 먼저 알려주도록 하겠다.

우선 우리는 Day_7에서 과정 3까지 진행했었다. (간단한 스타일 적용 완료.)

따라서 이번에는 4번 5번을 진행할 예정인데, 5번의 경우 조금 더 다양한 선택이 가능하도록 만들 것이다.

(왜냐.. 우리는 이제 한번 해놓으면 다 알 수 있는 개발자들이기 때문이죠.)

 

그러기 위해서는, 1의 데이터에 추가적으로 속성 추가해야 한다.

결과물에서 보다시피, 우리가 사용하는 버튼의 내용은 다음과 같다.

  • 전체 메뉴
  • 메인 메뉴 (밥이 제공되는 메뉴, 비빔밥, 김치찌개, 불고기를 메인 메뉴로 선정)
  • 고기가 들어간 메뉴
  • 사이드 메뉴 (5천원 이하 메뉴, 잡채와 떡볶이를 사이드 메뉴로 선정)

이중 메인 메뉴사이드 메뉴의 경우, 새롭게 속성지정해줘야 한다.

(나머지는 따로 속성 지정 없이 filter 적용이 가능하다.)

따라서 우리는 description 뒤에 추가적으로 price(가격) 와 category 라는 객체를 만들 것이다.

 

새롭게 만든 메뉴 데이터 (가격 및 카테고리 추가)

const menuItems = [
	{ name: '비빔밥', description: '밥 위에 나물, 고기, 고추장 등을 얹고 비벼 먹는 한국 요리', price: '8,000', category:'main' },
	{ name: '김치찌개', description: '김치와 돼지고기 등을 넣고 끓인 한국의 찌개 요리', price: '8,000', category:'main' },
	{ name: '불고기', description: '양념한 고기를 구워서 먹는 한국 요리', price: '8,000', category:'main' },
	{ name: '떡볶이', description: '떡과 어묵을 고추장 양념에 볶아 만든 한국의 간식', price: '3,000', category:'side'},
	{ name: '잡채', description: '당면과 여러 채소, 고기를 볶아 만든 한국 요리', price: '5,000', category:'side' }
	];

 

위의 내용을 복사하여 기존에 있던 내용에 덮어써주면 된다.

 

 

렌더링 응용 1단계 - filter  알아보기

지난 게시물에 이어 배열 관련 메서드 중 filter 에 대해 알아보도록 하겠다.

간단하게 관련 메서드의 기능을 정리하자면, 반복문 대신 배열의 각 요소를 순회하며

특정 작업을 수행하거나 신규 배열 생성에 사용된다고 생각하면 된다. (feat. 딸-깍)

그중, 조건을 만족하는 요소만을 모아 원하는 배열을 새롭게 만드는 메서드로 생각하면 된다.

(문자 뜻 그대로 필터링해서 값을 출력한다고 생각하면 편하다.)

 

filter() 활용 예시

/* filter() 활용 (1) : 3 이하의 값만 출력하도록 */
const numbers = [1, 2, 3, 4, 5];
const numUnder3 = numbers.filter(num => num <= 3); // 출력 : [1, 2, 3]

/* filter() 활용 (2) : 'B'가 포함된 이름만 출력하도록 */
const names = ['Bob', 'Beth', 'David', 'Jay'];
const letterB = names.filter(name => name.includes('b') || name.includes('B')); 
// 출력 : ['Bob', 'Beth']

 

이를 활용하여 각각의 속성별 스크립트를 작성하면 다음과 같다.

(잘 모를 수도 있으니, 각 속성에 대한 내용을  코드 내부에 첨부하도록 하겠다.) 

 

작성된 속성별 스크립트

const menuItems = [
	{ name: '비빔밥', description: '밥 위에 나물, 고기, 고추장 등을 얹고 비벼 먹는 한국 요리', price: '8,000', category:'main' },
	{ name: '김치찌개', description: '김치와 돼지고기 등을 넣고 끓인 한국의 찌개 요리', price: '8,000', category:'main' },
	{ name: '불고기', description: '양념한 고기를 구워서 먹는 한국 요리', price: '8,000', category:'main' },
	{ name: '떡볶이', description: '떡과 어묵을 고추장 양념에 볶아 만든 한국의 간식', price: '3,000', category:'side'},
	{ name: '잡채', description: '당면과 여러 채소, 고기를 볶아 만든 한국 요리', price: '5,000', category:'side' }
        ];

	/* 초기 화면 렌더링 값 (전체 메뉴 활용 가능) */
	function Menu() {
	let menuList = document.querySelector('#menu-list');

	/* ${item.price} 뒤에 '원'을 붙이지 않으면, 숫자만 출력되니 참고하자. */
	menuList.innerHTML = menuItems.map(item => `
		<li class="menu-item">
			<h2 class="menu-item__tit">${item.name}</h2>
			<p class="menu-item__txt">${item.description}</p>
			<p class="menu-item__txt"><b>${item.price}원</b></p>
		</li>
		`).join('');
	}

	/* 고기를 포함한 메뉴 */
	function meat() {
	let menuList = document.querySelector('#menu-list');
	let meatItems = menuItems.filter(item => item.description.includes('고기'));

	menuList.innerHTML = meatItems.map(item => `
		<li class="menu-item">
			<h2 class="menu-item__tit">${item.name}</h2>
			<p class="menu-item__txt">${item.description}</p>
			<p class="menu-item__txt"><b>${item.price}원</b></p>
		</li>
            `).join('');
	}

	/* main이라는 카테고리를 가진 메뉴 (메인 메뉴) */
	function main() {
	let menuList = document.querySelector('#menu-list');
	let mainItems = menuItems.filter(item => item.category.includes('main'));

	menuList.innerHTML = mainItems.map(item => `
		<li class="menu-item">
			<h2 class="menu-item__tit">${item.name}</h2>
			<p class="menu-item__txt">${item.description}</p>
			<p class="menu-item__txt"><b>${item.price}원</b></p>
		</li>
			`).join('');
	}

	/* 가격이 5000원 이하인 메뉴 (사이드 메뉴) */
	function sideMenu() {
	let menuList = document.querySelector('#menu-list');
	let sideItems = menuItems.filter(item => item.category === 'side' && parseInt(item.price) <= 5000);

	menuList.innerHTML = sideItems.map(item => `
		<li class="menu-item">
			<h2 class="menu-item__tit">${item.name}</h2>
			<p class="menu-item__txt">${item.description}</p>
			<p class="menu-item__txt"><b>${item.price}원</b></p>
		</li>
			`).join('');
	}

/* 페이지가 완전히 로드된 후 특정 작업을 수행하도록 만드는 이벤트 핸들러 */
window.onload = function () {
	Menu();
	};

 

 

렌더링 응용  2단계 - 내용 정리 및 결과물 확인

스크립트는 정리되었지만, 간과한 것이 하나 있으니.. 바로 html을 수정하지 않았다는 점이다.

스크립트'만' 넣어봤자 뼈대에 해당 내용을 포함하지 않는다면.. 아무 쓸모가 없으니 참고하자.

html은 결과물과 같이 버튼을 넣어 해당 함수를 수행할 수 있게끔 만들어보도록 하겠다.

 

html 정리 (<body> 부분)

    <div>
        <h1 class="tit">한식 메뉴</h1>
        <div class="btn-wrap">
            <button onclick="Menu()" class="btn">전체 메뉴</button>
            <button onclick="main()" class="btn">메인 메뉴</button>
            <button onclick="meat()" class="btn">고기가 포함된 메뉴</button>
            <button onclick="sideMenuUnder5000()" class="btn">사이드 메뉴</button>
        </div>
        <ul id="menu-list"></ul>
    </div>

 

뼈대가 정리되었으면, 다음은 CSS로 버튼을 꾸며줄 차례다.

이번엔 새롭게 호버 기능에 대해 알아보도록 하자.

버튼 주변에 커서를 가져갔을 때, 색상이 변하는 효과를 주고 싶을 때가 있을 것이다.

이럴 때는 호버 기능을 활용하면 되는데, 되도록이면 기존 버튼과 다른 배경색이나 글꼴색을 지정해 주자.
(그래야 잘 작동되는지 알 수 있기 때문이죠.)

 

CSS 정리 (지난 게시물 완성 코드에 이어 붙여주면 된다.)

/* 버튼 전체 영역 정리 */
.btn-wrap {
	text-align: center;
	margin-bottom: 20px;
	padding: 20px;
	}

/* 각 버튼 디자인 */
.btn {
	width: 200px;
	height: 40px;
	font-size: 16px;
	border: transparent;
	border-radius: 5px;
	margin: 0 10px;
	}

/* 호버 기능 사용은 아래처럼 만들면 된다. */
.btn:hover {
	background-color: rgb(170, 170, 170);
	color: white;
	}

 

 

마무리

너가 매번 새벽에 끝내서 그래... 조금 더 부지런해지렴.

 

드으으디어 전체 퀘스트 3가지 중 2개를 끝냈다. ㅇ<-<..

확실하게 처음 실습일기에서 열심히 적다보니.. 이번에는 보다 어렵지 않게(?) 수행할 수 있었다.

(거짓말입니다. 너 5천원에서 냅다 굴렀잖아.)

이것저것 생각을 하다보니 작성이 매번 새벽에 끝나서.. (너무 널널하게 작성한 자의 최후_ver.2)

아침부터 열심히 작성하다보면 해결되지 않을까.. 싶다 🥲  (과연 그럴지는 투비컨티뉴..⭐️)

여튼 얼레벌레 이번주도 TIL 알차게 마무리-!

다음주에 봅시다. 그럼 20000.

 

 

코드스니펫 (복사해서 빈 공간 안에 넣어주면 된다.)

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 한식 메뉴 </title>
    <style>
	h1 {
            display: block;
        }
        
        body {
            font-family: Arial, Helvetica, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
            padding: 40px 20px;
            background-color: #f6f6f6;
        }

        * {
            margin: 0;
            padding: 0;
        }

        .tit {
            font-size: 30px;
            text-align: center;
            margin: 0 0 30px;
        }

        .menu-item {
            text-align: center;
            padding: 30px;
            margin: 10px auto;
            border-radius: 10px;
            background-color: #fff;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        .menu-item__tit {
            font-size: 24px;
            margin: 0;
        }

        .menu-item__txt {
            font-size: 16px;
            color: #333;
            margin: 10px 0 0;
        }

        ul{
            list-style:none;
            padding-left:0px;
        }

	.btn-wrap {
            text-align: center;
            margin-bottom: 20px;
            padding: 20px;
        }

        .btn {
            width: 200px;
            height: 40px;
            font-size: 16px;
            border: transparent;
            border-radius: 5px;
            margin: 0 10px;
        }

        .btn:hover {
            background-color: rgb(170, 170, 170);
            color: white;
        }
        
    </style>
</head>
<body>
    <div>
        <h1 class="tit">한식 메뉴</h1>
        <div class="btn-wrap">
            <button onclick="Menu()" class="btn">전체 메뉴</button>
            <button onclick="main()" class="btn">메인 메뉴</button>
            <button onclick="meat()" class="btn">고기가 포함된 메뉴</button>
            <button onclick="sideMenu()" class="btn">사이드 메뉴</button>
        </div>
        <ul id="menu-list"></ul>
    </div>
</body>
<script>
        const menuItems = [
            { name: '비빔밥', description: '밥 위에 나물, 고기, 고추장 등을 얹고 비벼 먹는 한국 요리', price: '8,000', category:'main' },
            { name: '김치찌개', description: '김치와 돼지고기 등을 넣고 끓인 한국의 찌개 요리', price: '8,000', category:'main' },
            { name: '불고기', description: '양념한 고기를 구워서 먹는 한국 요리', price: '8,000', category:'main' },
            { name: '떡볶이', description: '떡과 어묵을 고추장 양념에 볶아 만든 한국의 간식', price: '3,000', category:'side'},
            { name: '잡채', description: '당면과 여러 채소, 고기를 볶아 만든 한국 요리', price: '5,000', category:'side' }
        ];

        function Menu() {
            let menuList = document.querySelector('#menu-list');

            menuList.innerHTML = menuItems.map(item => `
                <li class="menu-item">
                    <h2 class="menu-item__tit">${item.name}</h2>
                    <p class="menu-item__txt">${item.description}</p>
                    <p class="menu-item__txt"><b>${item.price}원</b></p>
                </li>
            `).join('');
        }

        function meat() {
            let menuList = document.querySelector('#menu-list');
            let meatItems = menuItems.filter(item => item.description.includes('고기'));

            menuList.innerHTML = meatItems.map(item => `
                <li class="menu-item">
                    <h2 class="menu-item__tit">${item.name}</h2>
                    <p class="menu-item__txt">${item.description}</p>
                    <p class="menu-item__txt"><b>${item.price}원</b></p>
                </li>
            `).join('');
        }

        function main() {
            let menuList = document.querySelector('#menu-list');
            let mainItems = menuItems.filter(item => item.category.includes('main'));

            menuList.innerHTML = mainItems.map(item => `
                <li class="menu-item">
                    <h2 class="menu-item__tit">${item.name}</h2>
                    <p class="menu-item__txt">${item.description}</p>
                    <p class="menu-item__txt"><b>${item.price}원</b></p>
                </li>
            `).join('');
        }

        function sideMenu() {
        let menuList = document.querySelector('#menu-list');
        let sideItems = menuItems.filter(item => item.category === 'side' && parseInt(item.price) <= 5000);

        menuList.innerHTML = sideItems.map(item => `
            <li class="menu-item">
                <h2 class="menu-item__tit">${item.name}</h2>
                <p class="menu-item__txt">${item.description}</p>
                <p class="menu-item__txt"><b>${item.price}원</b></p>
            </li>
        `).join('');
    }

        window.onload = function () {
            Menu();
        };

</script>
</html>
728x90
반응형