개발하는 디자이너 챌린지 - 04
지난 시간에는 스페셜 메뉴 데이터들이 컴포넌트들의 props에 어떻게 흘러들어 가서 프로젝트를 구성하는지를 살펴봤다면, 이번에는 각 컴포넌트들의 세부적인 동작을 담당하는 state라는 개념을 살펴보겠습니다. 추가적으로 UI라이브러리로 사용된 MUI의 스타일 방식도 살펴보겠습니다.
이번 에피소드에 사용된 v0 예제 코드는 아래와 같습니다.
코드 링크:
https://v0.dev/chat/DrvfOW4XXlQ
예제 사이트 링크:
https://kzmljn8864pt4jdlsshw.lite.vusercontent.net/
일단 이전 버전의 사이트는 전 세계 스타벅스 메뉴들을 표현하기에는 너무 플랫 한 느낌이 들었습니다. 그래서 처음 로고와 메뉴 지도섹션에서는 스타벅스의 브랜드 칼라를 강하게 표현하고 그 밑에 메뉴들을 다채로운 색으로 표현하면 어떨까 싶었습니다. 다만 메뉴들의 자료가 없거나 이미지들이 느낌이 다 달랐기 때문에 미드저니를 사용해서 파스텔 톤의 푸드 일러스트레이션으로 통일시켰습니다.
유사한 스타일을 유지하기 위한 midjourney pormpt로 스타벅스의 메뉴명만 바꿔서 제작하니 생각보다 균일한 톤의 이미지들이 나오네요. 이미지 내에서 음료의 크기가 조금씩 다른 건 아쉽지만 일단 넘어갑니다.
그리고 최상단의 맵 섹션에서는 스타벅스의 브랜드 칼라를 강조했다면 메뉴 리스트 섹션에서는 각 스페셜 메뉴의 메인색을 카드 UI의 배경색으로 반영해서 좀 더 다채로운 느낌을 살려봅니다.
지난 에피소드에서 props에 대해서는 이미 많이 얘기했지만 컴포넌트들을 동작하기 위해서는 state라는 개념을 잘 이해할 필요가 있습니다. state는 말 그대로 해당 컴포넌트의 상태를 관리하는 동적인 데이터라고 이해하시면 됩니다.
스타벅스 스페별 메뉴의 모든 정보를 담은 json파일을 App.js에서부터 시작해서 모든 컴포넌트에 props로 전달했죠. 이러한 데이터는 고유한 정보를 담고 있기 때문에 props로 전달해서 정적인 내용을 나타냅니다.
하지만 어떤 데이터들은 시간이나 특정 조건 (사용자의 인터랙션, 내려받은 props의 조건 등등)에 따라 수정할 필요가있습니다. 예를 들어 메뉴 20개를 한 번에 보여주는 것이 너무 많아서 chip UI로 대륙별 메뉴를 필터링하도록 하였는데, 이때 '현재 선택된 지역'이 어디인지 저장하기 위한 state가 필요합니다.
리액트 공식문서 설명
https://ko.react.dev/learn/state-a-components-memory
코드가 좀 길지만, 위에서부터 찬찬히 살펴보면, state를 쓰기 위해서는 useState라는 hook을 react에서 불러와야 합니다. useState를 사용하는 문법은 아래와 같은데
먼저 2개 길이의 배열을 선언하고 여기에 해당 state의 초기값을 담은 useState를 부여하면 됩니다. 이게 무슨 원리이지? 무슨 뜻이지? 혼란스럽겠지만 우리가 언어를 처음 배울 때 그냥 외우는 것처럼 배열의 첫 번째가 state값에 해당되고 두 번째가 state를 수정하는 함수에 해당한다고 이해하시면 됩니다. MenuListSection에는 총 3개의 state가 사용되었습니다.
- 선택된 대륙
- 선택된 대륙에 따른 필터링된 메뉴
- 메뉴리스트에서 뽑아낸 대륙 리스트
일단 Chip UI가 작동되는 state원리만 설명해 볼 테니 나머지는 여러분이 직접 리뷰해 보시길 바랍니다.
여기서 잠깐!
아마 이전 에피소드를 자세히 읽어보신 분들은 기억하겠지만 저는 이 프로젝트에서 google의 MUI를 사용하고 있습니다. MUI가 가장 안정적이고 널리 사용된 UI 라이브러리이기도 하지만 가장 큰 이유는
여러분이 불필요한 UI작업을 생략하고 미리 만들어진, 그리고 미리 준비된 가이드를 최대한 활용해서 학습에만 집중하기 위함입니다. 따라서 chip이 정확히 어떤 컴포넌트인지 모르겠다 혹은 저 코드에 있는 props가 정확히 어떤 역할을 하는 것인지 모르겠다 하면 MUI 공식문서를 살펴보면 됩니다.
계속 반복해서 얘기하지만 개발의 50%는 사전을 찾아보는 과정과 같다고 해도 과언이 아닙니다.
https://mui.com/material-ui/react-chip/#basic-chip
지난 시간에 배운 Array의 map함수를 이용해서 대륙리스트를 Chip 컴포넌트를 바인딩합니다. 그리고 Chip의 props에 알맞은 값들을 전달하는데
key - 배열로 바인딩된 모든 리액트 컴포넌트에는 고유 key 값을 넣어줘야 합니다. 기능에는 어떠한 영향을 미치진 않습니다.
label - 칩에 표시될 글자로 대륙명을 그대로 전달합니다.
onClick - 모든 리액트 컴포넌트에 적용할 수 있는 클릭 이벤트 핸들러입니다. 클릭이 발생했을 때 호출하는 함수를 전달합니다. 위에서 정의한 handleChipClick이란 함수를 array function에 넣어서 전달합니다. 이렇게 하는 이유는 심화과정 때 설명드릴 테니 일단 이것도 외우시길 바랍니다.
color, variant를 설명하기 전에 중요한 조건부 표현식을 알려드리겠습니다. 만약
condition ? A: B
라는 표현이 있다면 condition이 참이면 A 아니면 B를 반환하라는 뜻입니다. 따라서
selectedContinent === continent ? 'primary' : 'default'
선택된 대륙이 해당 칩의 대륙과 같다면 primary 색을 사용하고, 아니면 default를 사용하라는 뜻입니다.
여기서 주의해야할 것이
등호를 한번 사용하면 (A=B)
A에 B를 부여하라는 뜻이며
두 번 사용하면 (A==B)
A와 B의 값이 값은가?라는 조건부 식입니다, 같으면 true, 틀리면 false라는 boolean 값을 반환합니다.
세 번 사용하면 (A===B)
A와 B의 값이 type을 포함하며 정확히 일치하는가?라는 조건부 식입니다. 일단 특정 값이 같은지 비교할 때는 관습적으로 대부분의 경우 이 식을 사용합니다.
위와 같은 작동이 가능한 이유를 handleChipClick의 함수 안을 들여다보면서 살펴보겠습니다.
매우 간단합니다. 각 chip에서 전달한 대륙값을 인자로 받아서 현재 선택된 대륙 state값을 정하는 함수에 전달합니다. 즉 해당 chip을 선택한 순간 selectedContinents 값이 해당 대륙으로 변하기 때문에 글자색과 chip의 variant를 변하게 하는 것입니다.
color와 variant에 사용된 단어들도 MUI 공식문서에서 어떤 의미인지 찾아볼 수 있습니다. primary라는 단어는 MUI에서 사용자가 지정한 메인 컬러이며, default는 아무런 설정이 없을 때 MUI에서 지정한 색을 뜻합니다.
그리고 variant에서 outlined, filled는 이미 유추하셨겠지만 Button, Chip처럼 클릭커블한 컴포넌트의 스타일을 어떻게 표현할 것인지 결정하는 역할을 합니다.
그리고 마지막 섹션 TastingNoteSection에서도 각 테이스팅 노트에 해당되는 메뉴들을 모달로 보여줄 때 state를 사용했는데 이 부분도 한번 직접 리뷰해 보시길 바랍니다.
아마 MUI 문서를 처음 보면 조금 어려울 수 있습니다. 하지만 이것을 활용하는 것이 학습에 훨씬 도움이 된다는 점을 다시 한번 강조드립니다. 이미 만들어진 라이브러리를 사용하지 않으면 여러분이 아주 기본적인 것부터 직접 코딩을 해야 할 부분이 많아지기 때문입니다.
그리고 이 이유뿐 아니라 요즘은 많은 스타트업들이 MVP를 만들 때도 이미 만들어진 디자인 시스템을 적극 활용하는 추세입니다. 예전에는 이미 있는 디자인 시스템의 의존성이 높아지면 스타일을 바꾸는 것이 제한되는 불편함이 있었지만
최근 버전들을 살펴보면 다양한 스타일링 방식과 그 범위가 넓어지고 있고, 이미 갖추어진 기능 및 환경들의 이점이 너무 좋기 때문에 사용하지 않으면 오히려 손해라는 생각이 듭니다.
위 사이트에서 제공하는 버전이 여러 개인데 저희가 사용할 것의 정확한 명칭은 Material UI입니다. 가장 기본적인 버전이고 아래 링크에서 확인하세요.
https://mui.com/material-ui/getting-started/
일단 위 사이트의 왼쪽 사이드 메뉴에서 몇 가지만 설명하면
- components: 컴포넌트 스펙과 예제를 곁들인 props 사용법
- components api: 컴포넌트에 포함된 모든 props와 함수등이 자세히 설명되어 있습니다.
- customization: 색, 타이포, 스페이스, shape 등 다양한 요소들을 어떻게 커스텀하는지에 대한 설명입니다.
나중에 figma community에서 검색해 보시면 MUI 유료키트도 제공하는데 이 키트는 MUI의 개발 환경과 정확히 일치된 property와 variable이 적용된 figma 라이브러리입니다.
이 챌린지 기간 동안에는 일단 'components' 부분만 자세히 보셔도 많은 도움이 됩니다. 위에서 언급된 Chip 부분을 같이 확인해 보자면.
위와 같은 식으로 각 예제 코드를 여러 경우에 맞춰 설명해 줍니다. 중간에 extend code 버튼을 누르면 위 화면과 같이 import 구문까지 포함된 코드 전체를 볼 수 있습니다.
좀 더 내려보니 색생과 아이콘을 넣는 방식에 대한 예제도 친절하고 보여줍니다.
새로운 언어를 배울 때는 문장을 통째로 외워라
여러분 학행 때 위와 같은 말을 여러 번 들어본 적 있으시죠?
예를 들어 우리가 기껏 영단어 200개 정도 외웠다고 해서 마치 수학공식 조합하듯이 관용적인 표현을 제멋대로 써버리면, 미국인 입장에서 이해할 수 도 있겠지만 매우 어색하거나 오해의 소지가 있는 소통이 될 것입니다.
그래서 자주 쓰이는 정확한 문장을 그냥 통째로 외우라는 것이고, 이것은 언어적인 관점에서 '유의미한 패턴'이라고 할 수 있죠.
위에서 언급한 MUI 공식 문서에 나타난 예제 또한 마찬가지입니다. 저 코드를 모두 달달 외울 필요는 없겠지만 적어도 내가 사용할 컴포넌트에 어떤 '사용 패턴'이 있는지는 먼저 파악하시고 이를 그대로 쓰거나 좀 더 응용하시면 됩니다.
그래서 개발을 빨리 배우는 사람은 모든 걸 오차 없이 다 이해하려는 것보다 일단 만들고 싶은 것에 필요한걸 빨리 찾고, 이미 있는 패턴을 잘 이용하는 사람들입니다. 그래서 저 문서를 계속 활용하는 능력이 중요합니다.
특히나 나중에 Cursor AI를 활용하면 특정 라이브러리의 문서 자체를 학습시킬 수 있는데, 이런 환경에서 내가 예제에 익숙하고 각 패턴들에 어떤 요소들이 이는지 알고 있는 건 매우 중요하겠죠.