1. Sub 메뉴바 구현
어디서든 원하는 페이지로 이동할 수 있도록 네비게이션 메뉴바를 만들었다. CSS 를 활용하여 구현.
버튼에 마우스를 올렸을때, 컨텐츠 박스의 display 를 none 에서 block 으로 바꾸어 나타나게 했다.
:hover {.dropdown-content {display: block;}}
import React, { ReactElement } from "react";
import styled, { keyframes } from "styled-components";
export default function SubNav(): ReactElement {
const Main = styled.span`
/* border: 3px solid red; */
position: relative;
top: 0%;
display: flex;
flex-direction: column;
justify-content: center;
`;
const Dropbtn = styled.i`
/* background-color: yellow; */
/* color: white; */
position: absolute;
top: 0.5rem;
right: 0.5rem;
padding: 16px;
font-size: 25px;
border: none;
:hover {
.dropdown-content {
display: block;
}
}
`;
const Contents = styled.div`
display: none;
position: absolute;
right: 1rem;
top: 3rem;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
:hover {
display: block;
}
`;
const Content = styled.a`
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
:hover {
background-color: #ddd;
}
`;
return (
<Main>
<Dropbtn className="fas fa-book-open">
<Contents className="dropdown-content">
<Content href="/">홈</Content>
<Content href="/creatediary">일기쓰기</Content>
<Content href="/diaryview">일기보기</Content>
<Content href="/diarypublic">훔쳐보기</Content>
<Content href="/userinfo/calendar">나의정보</Content>
</Contents>
</Dropbtn>
</Main>
);
}
출처: codepen.io/simjihun/pen/xBjJOy?editors=1100
2. 버튼 클릭시 페이지 이동
리액트에선 페이지 이동방법이 여섯가지 정도가 있다.
핵심은 React-Router-DOM 의 활용.
:리액트 라우터는 리액트의 서드파티 라이브러리로 화면전환을 도와주는 역할을 한다. 일반적인 웹에서 a태그를 이용해 다른 페이지로 이동했었다면, 리액트에서는 리액트 라우터를 통해 Link 태그를 사용하여 화면을 전환한다. 리액트는 변화가 있는 컴포넌트만 업데이트하여 효율적으로 성능을 관리하는 구조로, 페이지 이동 시에도 굳이 화면 전체를 새로고침 할 필요가 없기 때문이다. 사실 리액트 라우터 없이도 컴포넌트 업데이트를 통해 화면전환을 할 수 있다. 그럼에도 리액트 라우터를 사용하는 이유는 사용자에게 새로고침, 뒤로가기, 즐겨찾기 등의 기능을 제공하기 위함이다.
(출처: velog.io/@jiasong214/React-React-Router-DOM)
1. BrowserRouter(or HashRouter)
BrowserRouter: 페이지 그 자체를 이동시키는 방식. history API를 사용해 URL과 UI를 동기화하는 라우터입니다.
HashRouter는: #을 포함시키고 해당 정보에 접근하는 방식
2. Route path 이용
Route는 페이지 하나를 통제하며 path, exact, component, render를 다룰 수 있게 해줍니다.
- path: 페이지를 이동할 경로를 선언합니다. 만약 선언하지 않으면 기존에 선언된 경로 이외에 접근시 라우팅
- exact: path가 정확하게 일치할 때만 이동하도록 선언합니다. (default true)
- component: 어떤 페이지인지 선언합니다.
- render: 커스터마이징이 가능한 컴포넌트를 함수 형태로 선언합니다.
3개의 라우트는 모두 /라는 path를 포함하기 때문에 어떠한 페이지를 접근하든지 / 페이지도 렌더링 된다.
따라서 exact 를 사용하여 '/' 경로만 포함된 컴포넌트를 출력한다.
3. Switch 이용
라우트들을 묶어서 선택된 라우트 첫번째 하나만을 렌더링.
경로가 / 인 라우트가 맨 상위에 있을 경우 어떤 페이지로 이동하던 결과는 Signpage 일 것. 따라서 맨 마지막에 위치시켜준다.
사용하지 않을 경우 매칭되는 모두를 렌더링합니다.
3. Render 로 커스터마이징 이동
페이지를 직접 커스터마이징하여 렌더링하는 방식으로 함수 형태로 선언해줍니다.
경로 뎁스를 늘려서 중복 되지 않게...!
4. Location, History
라우트로 페이지를 선언하게 되면 기본적으로 가지고 있는 props가 있는데 그 중 가장 유용하게 사용되는 것이 바로 location과 history. 이를 활용하여 특정 페이지의 예외 처리를 한다거나 history 함수를 사용하여 페이지를 이동시킬 수 있습니다.
첫 번째 콘솔은 history이며 지원하는 여러가지 함수들을 해당 컴포넌트에서 사용할 수 있게 됩니다.
두 번째 콘솔은 location이며 각각 프로퍼티 별로 값이 있습니다. 현재는 /main에 접근해 있기 때문에 해당 pathname을 가진 상태입니다.
이걸 모든 컴포넌트의 헤더에 props로 넘겨줍니다.
pathname은 현재 접근해있는 URL의 경로를 나타내 줍니다.
즉, /sign으로 접근을 해 있다면 로그인 페이지만 보여줄 수 있도록 헤더가 사라지는 예외처리(return null)를 구현한 것입니다.
history 에 push 메소드를 이용하여 페이지를 이동시킵니다.
5. Link
a태그 흡사한데, a태그를 사용하면 페이지가 깜빡이면서 리프레시 되지만
Link는 새로운 페이지를 불러오는 것이 아닌 화면 전환을 시켜줍니다.
Link를 import 해준 뒤 a태그 대신 Link를 선언하고, Link는 href가 아닌 to를 사용하여 경로를 선언해줍니다.
6. 내가 사용한 방법
리액트 라우터 돔에서 useHistory 를 가져와 활용한 방법.
import React, { ReactElement } from "react";
import { useHistory, Link } from "react-router-dom";
import styled, { keyframes } from "styled-components";
import PropTypes from "prop-types";
export default function Mainnav(): ReactElement {
const history = useHistory(); //useHistory 사용하기 위한 선언.
중략....
return (
<Main>
<Navsole>
<Navin color={colorType.color1} />
<Navout color={colorType.color6} onClick={() => history.push("/creatediary")}>
일기쓰기
</Navout>
</Navsole>
<Navsole>
<Navin color={colorType.color2} />
<Navout color={colorType.color7} onClick={() => history.push("/diaryview")}>
일기보기
</Navout>
</Navsole>
<Navsole>
<Navin color={colorType.color3} />
<Navout color={colorType.color8} onClick={() => history.push("/diarypublic")}>
훔쳐보기
</Navout>
</Navsole>
<Navsole>
<Navin color={colorType.color4} />
<Navout color={colorType.color9} onClick={() => history.push("/userinfo/calendar")}>
나의정보
</Navout>
</Navsole>
<Navsole>
<Navin color={colorType.color5} />
<Navout color={colorType.color10}>제작자</Navout>
</Navsole>
</Main>
);
}
Mainnav.propTypes = {
color: PropTypes.string.isRequired,
};
각 방법들의 장단점을 더 알아보고 적용해야겠다.
'2020_BootCamp_Codestates > Final Project' 카테고리의 다른 글
20210302 - 0303 14,15일차 그림판 PNG 저장 구현 (2) | 2021.03.03 |
---|---|
20210301 13일차 그림판 적용 (0) | 2021.03.01 |
20210227 11일차 재충전 (0) | 2021.03.01 |
20210226 10일차 반응형웹_미디어쿼리 (0) | 2021.02.27 |
20210225 9일차 모달창 (0) | 2021.02.26 |