스크롤바의 위치에 따라 배경 및 아이콘 색상이 바뀌는 헤더를 만들었다.
(gif가 계속 올라가지 않아서, 캡쳐로 대신했다ㅠㅠ)
배경색 외에도 아이콘 색이 바뀌지만, 여기서는 배경색만 바꾸는 법을 작성한다. 아이콘도 같은 원리로 fill 색상만 변경해주면 된다.
// Header.tsx
import { useState, useEffect } from "react";
// styles
import {
HeaderContainer,
} from "./styles";
const Header = () => {
const navigate = useNavigate();
let currentUrl = window.location.pathname;
const [scrollPosition, setScrollPosition] = useState(0);
const [headerColor, setHeaderColor] = useState("#ffffff");
// Scroll 위치를 감지
const updateScroll = () => {
setScrollPosition(window.scrollY || document.documentElement.scrollTop);
};
useEffect(() => {
window.addEventListener("scroll", updateScroll);
return () => {
window.removeEventListener("scroll", updateScroll);
};
}, []);
// scroll 위치가 100이하라면 투명한 배경색을 지정하고, 아니면 흰색을 지정한다.
useEffect(() => {
if (currentUrl === "/" && scrollPosition < 100) {
setHeaderColor("transparent");
} else {
setHeaderColor("#ffffff");
}
}, [scrollPosition, currentUrl]);
return (
<HeaderFont>
<HeaderContainer headercolor={headerColor}>
// ... 중략
</HeaderContainer>
</HeaderFont>
);
};
export default Header;
// style.ts
import styled, { css } from "styled-components";
import { mainColor, blue, grey, white, black } from "../../../styles/Colors";
// header.tsx에서 내려준 headercolor를 props으로 받아 배경색을 지정한다.
// 자연스럽게 색상이 바뀌도록 transition 설정을 넣었다.
export const HeaderContainer = styled.div<{ headercolor: string }>`
display: grid;
grid-template-columns: 1fr 6fr 1fr;
position: fixed;
top: 0;
width: 100vw;
height: 60px;
z-index: 99999;
background-color: ${(props) => props.headercolor};
transition: background-color 0.2s ease-out;
box-shadow: ${(props) =>
props.headercolor !== "transparent"
? "0 2px 8px rgba(0, 0, 0, 0.1)"
: "none"};
`;
위처럼 styled-component에 prop으로 속성을 내려줄 때 몇가지 주의할 사항이 있다.
첫 번째, styled-component에서 prop을 내려줄 때는 "문자열"로 내려준다.
styled-component에서 모든 속성은 "문자열"로 변환되기 때문에, styled-component에서 number
나 boolean
값을 판별할 수 없다.
전달하고 싶다면 .toString()
등의 메서드를 사용해 "true"나 "false"의 문자열 값을 가지고 판별해야한다.
두 번째, styled-component에서 prop을 내려줄 때는 항상 소문자를 사용한다.
prop을 대문자로 내려주게 되면, 해당 prop이 컴포넌트의 HTML 속성이 아니라 React 컴포넌트로 인식되어 전달되어 에러가 발생한다.