当useEffect()中使用的依赖库之一更改时,Reactjs可重用组件未更新

dw1jzc5e  于 2023-11-18  发布在  React
关注(0)|答案(2)|浏览(102)

我有一个nextjs自定义组件,在点击页面的路径名之前添加区域设置,并为活动链接添加自定义样式。
这里是组件

"use client";

import { useLocale } from "next-intl";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React, { useEffect, useState } from "react";

export default function RoutingLink({
    children,
    href,
    className,
    activeClass
}: {
    children: React.ReactNode;
    href: string;
    className?: string;
    activeClass?: string;
}) {
    const currentLocale = useLocale();
    const pathname = usePathname();
    const [isLinkActive, setIsLinkActive] = useState<boolean>(false);
    useEffect(
        () => {
            if (pathname.slice(1) === href) {
                setIsLinkActive(true);
            }

            () => {
                setIsLinkActive(false);
            };
        },
        [pathname]
    );

    function handleActiveClass() {
        if (isLinkActive) {
            if (activeClass) {
                return activeClass;
            } else {
                return "text-primaryHover";
            }
        } else {
            return "";
        }
    }

    return (
        <Link href={`/${currentLocale}/${href}`} className={`${className} ${handleActiveClass()}`}>
            {children}
        </Link>
    );
}

字符串
这个问题发生在我创建了一个侧边栏标签组件 * 请看截图 *

,当我点击一个链接时,它变成活动的,样式改变,但在我点击另一个链接后,以前的链接仍然有活动的样式。
我尝试使用useEffect()将当前路径名作为依赖库传递给它,这样每当url被更改时,活动类就应该被更改,回调函数应该被调用,这样活动样式就从先前的链接中消失了。

cczfrluj

cczfrluj1#

这个问题似乎与您在useEffect钩子中设置和更新isLinkActive状态的方式有关。useEffect中的cleanup函数似乎结构不正确。此外,由于pathnamehref的比较方式,useEffect可能不会按预期触发。
让我们尝试一种不同的方法。您可以通过比较pathnamehref属性来直接在组件中计算活动状态,而不是依赖于useEffect来确定活动链接。
以下是可能解决此问题的组件的更新版本:

"use client";
import { useLocale } from "next-intl";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React from "react";

export default function RoutingLink({
    children,
    href,
    className,
    activeClass
}: {
    children: React.ReactNode;
    href: string;
    className?: string;
    activeClass?: string;
}) {
    const currentLocale = useLocale();
    const pathname = usePathname();

    // Check if the link is active based on the current pathname
    const isLinkActive = `/${currentLocale}/${href}` === pathname;

    function handleActiveClass() {
        return isLinkActive && activeClass ? activeClass : "";
    }

    return (
        <Link href={`/${currentLocale}/${href}`} passHref>
            <a className={`${className} ${handleActiveClass()}`}>
                {children}
            </a>
        </Link>
    );
}

字符串
这种方法基于构造的链接(/${currentLocale}/${href})和pathname之间的比较,直接在组件中计算isLinkActive状态。然后它相应地应用活动类,而不依赖于useEffect。这应该在路径名更改时更新活动类。
给予这个尝试,看看它是否解决了与活动类不更新时,URL更改的问题。

irtuqstp

irtuqstp2#

我认为Tailwind即使重新渲染组件也不会调用该函数。此外,如果同一页面上有多个链接,那么当点击其他链接时,旧的链接仍然会被挂载,这意味着useEffect上的回调函数不会被调用。
我建议你稍微重构一下:

const pathname = usePathname();
const isActive = pathname.slice(1) === href;
const linkClass = isActive ? activeClass || "text-primaryHover" : "";

return (
        <Link href={`/${currentLocale}/${href}`} className={`${className} ${linkClass}`}>
            {children}
        </Link>
);

字符串

相关问题