반응형 헤더
25902 단어 reactjavascriptbeginners
React에서 반응형 헤더를 만드는 것은 복잡할 것이라고 생각했는데 막상 구현해 보니 생각보다 훨씬 간단했습니다.
반응형 헤더를 만들 때 가장 먼저 생각해야 할 것은 크기가 조정될 때마다 화면을 측정하는 방식인 것 같습니다. 그리고 다행스럽게도 자바스크립트는 정확히 그 목적을 위한 eventListener,
resize
eventListener를 제공합니다.반응형 헤더를 만드는 목표를 달성하기 위해 해당 eventListener를 어떻게 활용할 수 있는지 봅시다.
// CustomHooks.js
import { useEffect, useState } from 'react';
export const useWindowWidthAndHeight = ()=>{
// 1- Get the size of window
let windowInnerSize = [window.innerWidth, window.innerHeight];
// 2- Define the state variable windowSize and pass windowInnerSize as its initial value
let [ windowSize, setWidowSize ] = useState(windowInnerSize);
useEffect(()=>{
const changeWindowSize = ()=>{
setWidowSize([window.innerWidth, window.innerHeight]);
}
/* 3- add a 'resize' eventListener to window so that whenever
the size of window changes the state variable windowSize changes and the component re-renders */
window.addEventListener("resize", changeWindowSize);
// 4- cleanup the 'resize' eventListener
return ()=> window.removeEventListener('resize', changeWindowSize);
}, []);
// 5- return the window size
return windowSize;
}
여기에서
useWindowWidthAndHeight
라는 사용자 지정 후크를 만듭니다.내부
useWindowWidthAndHeight
:먼저
windowInnerSize
의 현재 너비와 높이를 저장할 window
변수를 만듭니다.둘째,
windowInnerSize
Hook을 사용하여 생성한 상태 변수windowSize
의 초기 값으로 useState
를 사용합니다.셋째,
useEffect
Hook을 선언하여 resize
eventListner를 추가하여 창resize
이 발생하면 changeWindowSize()
가 화면의 새로운 측정windowSize
및 width
로 변경height
하도록 합니다.마지막으로
window
의 가장 최근에 측정된 너비와 높이를 반환합니다.이제 헤더를 생성해 보겠습니다.
// Header.js
import React from 'react';
import Navbar from './Navbar';
import { Link } from 'react-scroll'; // react-scroll is a library for scrolling in React
import SmallScreensNavbar from './SmallScreensNavbar';
import { useWindowWidthAndHeight } from './CustomHooks';
const Header = () =>{
// use our custom hook to get the the window size
const [width, height] = useWindowWidthAndHeight();
return(
<header>
<div className="header-inner">
<Link to="Home"
smooth={true}
className="logo nav-link">
RH
</Link>
{/*if the width of the window is bigger than 1000px use <Navebar/>,
else user <SmallScreensNavbar/>*/}
{ width > 1000 ?
<Navbar navClass="nav-big"
linkClassName="nav-big-link"/>
:
<SmallScreensNavbar navClass="nav-small"
linkClassName = "nav-small-link"
/>
}
</div>
</header>
)
}
export default Header;
이제 너비가 1000px보다 큰 화면과 작은 화면을 위한 두 개의 탐색 모음 구성 요소를 만들어야 합니다.
//Navbar.js
import React from 'react';
import { Link } from 'react-scroll';
const Navbar = ({navClass, linkClassName}) =>(
<NavComponent navClass={navClass}
linkClassName = {linkClassName}
/>
);
export const NavComponent = ({onClick, navClass, linkClassName})=>(
<nav className={navClass}>
{["Projects", "About", "Contact", "Footer"].map(section=>
<Link to={section}
smooth={true}
className={linkClassName}
onClick={onClick}>
{section}
</Link>
)}
</nav>
)
export default Navbar;
작은 화면의 경우:
//SmallScreensNavbar.js
import React, { useState } from 'react';
import { NavComponent } from './Navbar';
const SmallScreensNavbar = () =>{
// declare 'translate' as a state variable
let [translate, setTranslate ] = useState(true);
return(
<div>
<button className="hamburger-btn"
onClick= {()=> setTranslate(!translate)}> {/* toggle translate */}
{/* change the btn text based on whether translate is true or false */}
{translate?<span>☰</span>:<span>×</span>}
</button>
{/*hide and show the sidebar list based on whether translate is true or false*/}
<div id="sidebar-list" className={`${translate? "addTransiton": "removeTransition"}`}>
<NavComponent
navClass="nav-small"
linkClassName = "nav-small-link"
onClick = {()=>setTranslate(true)} //set translate to true to hide the sidebar list
/>
</div>
</div>
)
}
export default SmallScreensNavbar;
이제 이것이 작동하려면 CSS를 추가해야 합니다.
header{
position: fixed;
top: 0;
height: 70px;
background-color: rgb(197, 178, 178);
width: 100%;
display: flex;
align-items: flex-end;
justify-content: center;
box-shadow: 1px 1px 1px 1px rgba(116, 110, 110, 0.199);
}
.header-inner{
width: 90%;
display: flex;
align-items: center;
justify-content: space-between;
}
.hamburger-btn{
font-size: 1.3rem;
position: absolute;
bottom: 0;
width: 40px;
height: 35px;
right: 30px;
outline: none;
background-color: rgb(134, 125, 125);
color: whitesmoke;
}
.addTransiton{
transform: translateX(170px);
transition: transform 0.5s ease-in-out;
}
.removeTransition{
transform: translateX(20px);
transition: transform 0.5s ease-in-out;
}
#sidebar-list{
background-color: rgb(134, 125, 125);
height: 90vh;
width: 170px;
position: absolute;
z-index: 2000;
right: 0;
top: 0;
margin-top: 70px;
}
.nav-big{
list-style: none;
display: flex;
justify-content: space-around;
width: 70%;
font-weight: bold;
}
.nav-big-link{
cursor: pointer;
color: white;
text-decoration: none !important;
}
.nav-small{
display: flex;
flex-direction: column;
text-align: center;
justify-content: space-around;
margin: auto;
height: 40%;
margin-top: 50px;
width: 80%;
}
.nav-small-link{
cursor: pointer;
color: whitesmoke;
padding-bottom: 5px;
}
이제 모든 것이 작동해야 합니다.
읽어주셔서 감사합니다. :)
참조:
Stackoverflow 화면의 너비와 높이를 측정하는 방법을 알아보세요.
Reference
이 문제에 관하여(반응형 헤더), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hajarnasr/responsive-header-in-react-59h5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)