Next.Js에서 활성 링크를 대상으로 지정하고 스타일을 지정하는 방법(Typescript 사용)
20905 단어 javascripttypescriptnextjsreact
activeClassName
를 사용하여 활성 경로를 대상으로 합니다. 그러나 스타일이 지정된 활성 링크를 사용하여 Next.JS에서 탐색 구성 요소를 빌드하는 것은 간단하지 않습니다.Next.js에서 유사한 효과를 얻으려면 기본 제공
<Link>
구성 요소를 사용자 지정해야 합니다.Typescript를 사용하는 두 가지 솔루션인 기본 솔루션과 자세한(권장) 솔루션을 살펴보겠습니다.
기본 솔루션
이는 사용자 지정
ActiveLink
구성 요소와 useRouter
후크를 사용하는 기본 솔루션의 예입니다.//Set up your navigation component with a custom 'ActiveLink' component (imported) from a separate file.
// Then create a page route file and component for each 'href' path i.e. index.tsx, about.tsx, products.tsx
import ActiveLink from './ActiveLink';
const Nav = () => {
return (
<nav>
<ul className="nav">
<li>
<ActiveLink href="/">
Home
</ActiveLink>
</li>
<li>
<ActiveLink href="/about">
About
</ActiveLink>
</li>
<li>
<ActiveLink
href="/products/"
>
Products
</ActiveLink>
</li>
</ul>
</nav>
);
};
export default Nav;
다음으로 활성 링크 동작을 재생성하기 위해
ActiveLink
구성 요소를 빌드해 보겠습니다.import { useRouter } from 'next/router'
import { LinkProps } from 'next/link';
//LinkProps is a type that requires 'href' as a prop. We're extending it to include a react element as a children prop.
type ActiveLinkProps = LinkProps & {
children: ReactElement;
}
// href is the url path passed as a prop in the Nav component. The children are the string names passed in-between the ActiveLink tags.
function ActiveLink({ children, href }: ActiveLinkProps) {
// Deconstruct `asPath` from the router object to access the current page path shown in your browser (including the search params).
const {asPath} = useRouter()
//define the styling for the active link. If the current page path matches the 'href' path provided, display a red link. All other links will be black.
const style = {
color: asPath === href ? 'red' : 'black',
}
// Navigate to the page provided as 'href' when the link is clicked (router.push is used for client-side transitions)
const handleClick = (e) => {
e.preventDefault()
router.push(href)
}
//the active link will have a style of 'color:red'
return (
<a href={href} onClick={handleClick} style={style}>
{children}
</a>
)
}
export default ActiveLink
이것은 괜찮은 해결책입니다. 하지만 서버 측 렌더링, 동적 경로, 맞춤 링크 소품 등을 포함하도록 앱을 확장하려면 어떻게 해야 할까요?
다음은
ActiveLink
구성 요소에 대한 추가 조정입니다.권장 솔루션
먼저
Nav
구성 요소에서 activeClassName
문자열이 있는 active
소품을 각 페이지 경로의 ActiveLink
구성 요소에 추가합니다.또한/products, 즉/products/categories 내에 페이지를 중첩하기 위한 동적 "포괄"경로를 추가할 수 있습니다. 다음과 같이 페이지 폴더에 해당 페이지 경로를 생성해야 합니다.
import ActiveLink from './ActiveLink';
const Nav = () => {
return (
<nav>
<ul className="nav">
<li>
<ActiveLink activeClassName="active" href="/">
<a>Home</a>
</ActiveLink>
</li>
.....
//add the 'activeClassName' to each ActiveLink as shown in the previous section.
......
// this is an example of a dynamic route using query paramaters.
<li>
<ActiveLink
activeClassName="active"
href="/products/[...slug]"
as="/products/categories?limit=5"
>
<a>Products Categories </a>
</ActiveLink>
</li>
</ul>
</nav>
);
};
export default Nav;
둘째,
activeClassName
prop과 나중에 전달할 수 있는 추가 prop을 고려하여 ActiveLink 구성 요소를 수정하겠습니다.또한 페이지가 서버 측 렌더링을 사용하여 렌더링되는 경우
asPath
후크의 useRouter
가 경로 불일치로 이어지지 않도록 해야 합니다.이를 방지하기 위해 Next.js 문서에서는
isReady
사용을 권장합니다. 라우터 필드가 클라이언트 측에서 업데이트되는지 여부를 확인하는 데 사용되는 부울입니다.import { useRouter } from 'next/router';
import Link, { LinkProps } from 'next/link';
import React, { useState, useEffect, ReactElement, Children } from 'react';
//Add the activeClassName as a required prop
type ActiveLinkProps = LinkProps & {
children: ReactElement;
activeClassName: string;
};
const ActiveLink = ({
children,
activeClassName,
...props
}: ActiveLinkProps) => {
//deconstruct 'isReady' from the useRouter hook.
const { asPath, isReady } = useRouter();
//create an empty string as the default className of the component
const [className, setClassName] = useState('');
useEffect(() => {
// isReady checks if the router fields are updated client-side (it must be used inside a useEffect hook)
if (isReady) {
// URL().pathname will help to eliminate query and hash strings from the url.
// Props.as targets dynamic routes, whilst props.href targets normal static page routes.
const linkPathname = new URL(
(props.as || props.href) as string,
location.href
).pathname;
// Here we make use of 'asPath' in the correct context (once 'isReady' is true)
const activePathname = new URL(asPath, location.href).pathname;
// Attach the activeClassName to the matching current page
const newClassName =
linkPathname === activePathname
? `${activeClassName}`: '';
// Sets a new 'className' state if there is a mismatch between the current and previous state. This ensures a 'toggle' like behavior between link changes.
if (newClassName !== className) {
setClassName(newClassName);
}
}
// useEffect dependencies defined below
}, [
asPath,
isReady,
props.as,
props.href,
activeClassName,
setClassName,
className,
]);
return (
// return the in-built Next Link including a child (a clone the 'a' element (child) including the activeClassName if it is the active page)
<Link {...props}>
{React.cloneElement(child, {
className: className || null,
})}
</Link>
);
};
export default ActiveLink;
마지막으로 전역 css 스타일시트의
.active
에 스타일을 추가합니다(일반적으로 _app
tsx로 가져옴).
.active {
color: red;
}
.active:after {
content: ' (current page)';
}
당신은 이런 것을 봐야합니다 ...
요약
Next.Js에서 활성 링크를 대상으로 지정하고 스타일을 지정하는 간단한 솔루션은
useRouter
후크를 활용하여 현재 경로에 액세스하고 activeClassName
가 있는 Link 구성 요소를 반환하는 사용자 지정 Link 구성 요소를 만드는 것입니다.이
activeClassName
는 CSS를 통해 스타일을 지정하여 페이지 경로의 활성 링크를 표시할 수 있습니다.
Reference
이 문제에 관하여(Next.Js에서 활성 링크를 대상으로 지정하고 스타일을 지정하는 방법(Typescript 사용)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mayooear/how-to-target-and-style-the-active-link-in-nextjs-with-typescript-2hh0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)