깃허브 주소 ▼
개요
대략적인 학습이 끝났으니 이제 본격적으로 개발에 들어가려고 한다. 시행착오를 겪으면서 배우면 더 기억에 잘 남아서 무작정 만들기로 했다. 이번 목표는 네비게이션 바, 메인 버튼 2개을를 만드는 것이다. 메인 화면의 요소부터 만들고, 이후에 리스트 셀을 만든 후, 페이징, 그리고 네비게이팅에 대해 알아보려고 한다.
Flutter나 기존에 잘 아는 프레임워크 혹은 라이브러리를 사용했다면 아마 폴더 구조, 디자인 패턴, 네트워킹 방식, 데이터 처리 방식 등등 기본적인 것들을 정하고 들어갔을 테지만, 현재의 나는 React에 대해 아는 것이 거의 없다시피하니 필요한 걸 하나씩 알아가며 코딩하고자 한다.
네비게이션 바
필요한 것들 정의하기
우선 네비게이션 바 자체가 필요한 건 맞지만, 네비게이션에 무엇이 들어가서 필요한 지 부터 정해야했다. '웹 사이트들에 다 들어가니까~' 라는 이유로 무작정 만들었다가 시간만 날릴 수 있으니 우선은 어떤 페이지로 연결을 해야할 지 부터 생각을 해봤다.
1번: 가이드
가장 먼저 생각난 것은 가이드. 어떻게 사용하는지를 알아야 할 거 같아서 가장 잘 보이는 곳에 위치시켜야할 거 같다. 꼭 가이드가 아니더라도 FAQ와 같은 형식으로 자주 물어볼거 같은 요소들이나 서비스를 시작하기 위해 봐야하는 것들을 쉽게 볼 수 있는 페이지를 만들어야겠다고 생각했다. (이 부분은 앱에도 없어서 업데이트를 할 예정이다.)
2번: 문의
다음으로는 문의. 버그 리포트나 사용에 불편한 점들을 모아놓는 곳이 필요하다고 생각이 들었다. 신고 기능도 필요하긴 하지만, 신고는 각 딜레마 페이지에서 신고할 수 있도록 하는게 좋을거 같다. 그래서 게시물 당 1회 신고라는 규칙을 쉽게 지킬 수 있고, 지체없이 빠르게 신고도 할 수 있기 때문이다.
3번: 회원가입/로그인
마지막으로는 회원가입과 로그인 버튼이다. 엄연히 회원 기능이 있기 때문에 회원가입과 로그인버튼을 두어 로그인 할 수 있게 해줘야한다. 모바일 출시를 위해서 구글, 애플, 카카오 이렇게 3가지 SNS에서 회원가입 할 수 있게 할 예정이다. (앱스토어 정책상 소셜 로그인을 하나라도 넣는 이상, 애플 로그인도 넣어줘야 한다. 애플 로그인만 넣는거 OK, 소셜 로그인 없는거 OK, 하지만 소셜 로그인이 있지만 애플 로그인이 없는거 NOT OK.)
대강 만든 큰 틀
그렇게 만들어진 네비게이션 바는 이렇다. ▼
선택하면 흰색이 되게끔 설정해두었다. ▼
오른쪽으로 정렬하는 법을 잘 몰라서 검색해서 넣었다. 아주 당연하게도 아직 반응형 UI는 적용되어있지 않아 줄이면 모양이 이상해진다... 추후에 태블릿 버전과 모바일 버전도 만들 예정이다. 모바일 버전은 이미 디자인이 있어서 그 디자인대로 만들면 되는데, 태블릿 버전은 새롭게 만들어야해서 조금 걸릴거 같다.
코드
다 완성된 코드는 더보기를 누르면 볼 수 있다. ▼
NavigationBar.js 코드
import React from "react";
import styled, { css } from "styled-components";
import { theme } from "./ui/theme.js";
import NavbarLogo from "./NavbarLogo.js";
const StyledWrap = styled.div`
margin-top: 60px;
`;
const StyledNavigationBar = styled.div`
width: 100%;
display: flex;
z-index: 2000;
position: fixed;
top: 0px;
background: ${theme.color.background};
gap: 16px;
`;
const StyledListCell = styled.li`
list-style: none;
display: inline-block;
padding: 0px 30px 0px 10px;
color: ${theme.color.primary};
&:hover {
color: white;
transition: 0.5s;
}
& > * {
color: inherit;
}
`;
const StyledListWrap = styled.div`
margin-left: auto;
`;
const StyledAnchor = styled.a`
text-decoration: none;
font-family: "JalnanGothic";
`;
function NavigationBar() {
return (
<StyledWrap>
<StyledNavigationBar>
<NavbarLogo></NavbarLogo>
<StyledListWrap>
<ul>
<StyledListCell><StyledAnchor href="#hello">가이드</StyledAnchor></StyledListCell>
<StyledListCell><StyledAnchor href="#hello">문의</StyledAnchor></StyledListCell>
<StyledListCell><StyledAnchor href="#hello">회원가입/로그인</StyledAnchor></StyledListCell>
</ul>
</StyledListWrap>
</StyledNavigationBar>
</StyledWrap>
);
}
export default NavigationBar;
네비게이션 바에서 스타일을 넣어준 요소들은 `StyledWrap`, `StyledNavigationBar`, `StyledListWrap`, `StyledListCell`, `StyledAnchor`로 Styled-Component를 사용하면 앞에 `Styled`를 붙이기로 했다.
StyledNavigationBar, StyledWarp
5가지 요소를 만들고 넣으면서 선언하기 까다로웠던 부분을 좀 이야기해볼까 한다. 제일 먼저 네비게이션 상단 고정 부분이다. 한 번 하고나면 굉장히 쉽지만, 처음하는 입장에서 조금 까다로웠다.
네비게이션 바가 상단에 고정되어있어야 하기에 레이어를 설정해보기로 했다. 말이 레이어고 사실은 `z-index`를 사용하는건데, 무작정 2000을 넣어줘서 다른 어떤 요소들보다도 높게 설정되게 해놨다.
그런데 그냥 맨 위에 올라가게만 해놓으면 이렇게 요소들이 맨 위부터 시작해서 가려지는 문제가 있어서 StyledWrap을 만들고 margin-top을 넣어줬다. ▼
이렇게 넣어주고 나면 잘리는 부분 없이 잘 나오게 된다. ▼
StyledListCell
네비게이션 바에 들어있는 링크들에 마우스를 올리면 흰색으로 변하게 하고 싶어서 `hover`를 넣어주려고 했다. 그런데 Styled-Component에서 `hover`나 `link`는 어떻게 넣는지 조금 헤맸다. 기존에는 아래와 같은 방식으로 넣었는데, ▼
.logo:hover, .logo:link, .logo:visited, .logo:active {
color: #31E5AF;
}
이를 그대로 styled-component에 적용시키려고 하니 문법이 조금 이상하다는 생각이 들었다. 스타일이 백틱으로 들어가는데 `hover`, `link`, `visited` 와 같은 요소들은 같은 문법으로 작성할 수 없었다. 그래서 검색을 조금 해보니 아래와 같은 문법으로 작성한다고 적혀있었다. ▼
const StyledListCell = styled.li`
list-style: none;
display: inline-block;
padding: 0px 30px 0px 10px;
color: ${theme.color.primary};
&:hover {
color: white;
transition: 0.5s;
}
& > * {
color: inherit;
}
`;
기본적인 문법은 같으나, 어떤 요소의 `hover`인지를 파악하기 위해 `&` 기호를 통해 자기 자신임을 표현해준다. 이후에는 다른 문법들이랑 똑같이 작성해주면 큰 문제없이 작성이 가능해진다.
메인 버튼 2개
필요한 것들 정의하기
메인 버튼 2개에서 필요한 것은 아래의 스크린 샷에 나와있는 것 처럼 제목 텍스트와 설명, 그리고 우측 아래의 아이콘이다. ▼
대강 만든 큰 틀
현재까지 구현에는 아직 설명은 들어가있지 않다. 일단은 제목 텍스트와 우측 아래의 아이콘을 넣는 것만 해보았다. 사진에는 아이콘도 들어가있지 않은데, 이는 아이콘 파일을 아직 프로젝트에 넣어놓지 않았기 때문이다. 그래서 일단 아이콘은 들어갈 수 있지만, 아이콘을 넣어놓지는 않았다. ▼
코드
다 완성된 코드는 더보기를 누르면 볼 수 있다. ▼
SquareButton.js 코드
import React from "react";
import styled from "styled-components";
import { theme } from "./ui/theme.js";
const StyledSquareButton = styled.button`
width: 150px;
height: 150px;
display: flex;
flex-direction: column;
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: none;
background-color: ${theme.color.primary};
text-align: left;
`;
const StyledTopLeftText = styled.div`
color: black;
font-family: "JalnanGothic";
font-size: 20px;
white-space: normal;
word-break: keep-all;
`;
const StyledBottomRightImage = styled.div`
position: absolute;
bottom: 6px;
right: 12px;
`;
function SquareButton({ text, image, ...props }) {
return (
<StyledSquareButton {...props}>
<StyledTopLeftText>{text}</StyledTopLeftText>
<StyledBottomRightImage>{image}</StyledBottomRightImage>
</StyledSquareButton>
);
}
export default SquareButton;
SquareButtonContainer.js 코드
import React from "react";
import styled, { css } from "styled-components";
import SquareButton from "./SqureButton.js";
const StyledButtonContainer = styled.div`
display: flex;
justify-content: left;
align-items: left;
gap: 16px;
`;
function ButtonContainer() {
return (
<StyledButtonContainer>
<SquareButton text={"오늘 랜덤 딜레마"}></SquareButton>
<SquareButton text={"전체 딜레마"}></SquareButton>
</StyledButtonContainer>
);
}
export default ButtonContainer;
SqureButton과 SquareButtonContainer의 구조에 대한 고민
`SquareButton`을 만들고 이를 가로 정렬해줄 컨테이너를 만들었다. 이렇게 만드는게 효율적인가에 대해 생각을 해봤다. 현재는 `SquareButtonContainer`만 호출해주면 위의 사진과 같이 구현이 되지만, 이게 가능한 이유는 `SquareButtonContainer`안에 값들을 하드코딩 해놨기 때문이다. 현재로써는 이 기획이 바뀔 일이 없어서 이렇게 해놔도 동작에는 큰 문제가 없지만, 추후에 수정이 필요하게 되면 `SquareButton`의 제목이나 설명을 바꿔야할 수 있다. 그러면 아이러니하게도 호출은 `MainPage`에서 했지만 수정은 `SquareButtonContainer` 파일로 가서 해야한다. 디버깅과 수정에 있어 인지부조화가 올 수도 있겠다는 생각이 들었다.
그래서 이를 프로퍼티를 받게끔 수정하려고 했는데, 값이 4개가 생기기도 하고 나중에 버튼이 3개가 되면 수정이 복잡해지는 그런 문제가 생겨 프로퍼티를 어떻게 줄 지 고민중이다. 이는 다음에 투두에 넣어놓고 고민하다가 수정하기로 했다.
StyledTopLeftText 텍스트 정렬과 Word break
처음에 버튼을 만들 때 아래의 사진과 같이 단어도 깨지고, 정렬도 가운데 정렬이 되어 마음에 들지 않았다. 오른쪽 처럼 글이 짧으면 괜찮은데, 왼쪽 처럼 글이 조금 길어지면 괴상한 형태를 취하게 되어 이를 고치기로 했다. ▼
처음에는 `justify-content`와 `align-items`를 사용했다. 텍스트는 당연히 `left`로 정렬이 되어있을거라고 생각했고, 박스 내부의 요소들이 정렬되지 않아서 생기는 문제라고 생각하여 이 두가지 프로퍼티에 `flex-start`를 넣어주었다. 허나 바뀌는건 없었다. 진짜 문제는 `text-align`이었기 때문이다. `text-align`이 기본으로 `center`로 되어있어서 저렇게 나왔던 것이었고, 이를 `left`로 바꿔주니 정렬 문제는 해결이 되었다.
다음으로는 단어가 깨지는 현상이었다. 처음에는 `white-space`를 `normal`혹은 `nowrap`으로 설정하면 된다는 글을 보고 해봤는데 문제가 해결되지 않고 오히려 박스를 넘어 오른쪽으로 갔다. ▼
그래서 `white-space`가 정확히 어떤 일을 하는 프로퍼티인지 다시 찾아보니 `white-space`의 역할은 공백과 관련된 것이었다. 지금 문제는 공백으로 인해 생긴 문제가 아니므로 잘못된 접근이었다. 그래서 전에 Piema web에서 쭉 훑어보면서 word-...어쩌구 프로퍼티가 있었던거 같은데 하고 기억을 되살려 찾아보니 `word-break`라는 프로퍼티가 있었다. 이 프로퍼티에 `keep-all`을 할당해주니 문제가 해결됐다! ▼
const StyledTopLeftText = styled.div`
color: black;
font-family: "JalnanGothic";
font-size: 20px;
word-break: keep-all;
text-align: left;
`;
마치며
오늘은 styled-component에 대해 알아보고 사용해보는 시간을 가졌다. 아직은 크게 어렵지 않아서 금방 만들 수 있을거 같다. 써보면서 느낀 것은 CSS 파일을 만들고 하는 것보다 한 파일에서 모두 정의가 가능해지니까 왔다갔다 할 일이 없어 편하다는 것이다. 처음부터 이렇게 편하게 개발해도 되나? 싶긴 한데... 다음에 좀 더 깊이 학습할 수 있을 때 학습을 해보자. 우선은 하나하나 익혀가보자.
그래도 나름 코파일럿에 의지하지 않고 자력으로 열심히 하고 있다. 배우는 단계에서 코파일럿을 쓰면 잘 모르면서 코파일럿이 해주는걸 보고 내가 해냈다고 착각할거 같다는 생각이 들어서 코파일럿은 꺼놓고 코딩하고 있다. ▼
코파일럿... 해당 개발 스택에 대해 잘 알고 있다면 정말 좋은 도구지만 잘 모르면서 사용하면 큰 재앙이 될 거 같다. 나는 아직 React를 잘 모르니까 당분간은 계속 꺼놓자.
'Develop > React' 카테고리의 다른 글
[React][개발기] 6. Stateless하기 만들기, 페이지 만들기, 그리고 Map 활용 (0) | 2024.07.17 |
---|---|
[React][개발기] 5. Component 이어서 만들기와 고민 해결 (0) | 2024.07.16 |
[React][개발기] 3. 우선 기초적인 것들부터 학습2(HTML, CSS, JS) (0) | 2024.07.14 |
[React][개발기] 2. 우선 기초적인 것들부터 학습(HTML, CSS) (0) | 2024.07.13 |
[React][개발기] 1. React! 근데 React를 왜 써? (0) | 2024.07.13 |