我用的是Preline,在动态页面上,为什么要反复重新初始化?我用的是Next.js;不是应该只需要初始化一次吗?

问题描述 投票:0回答:1

我正在使用 preline 并在动态页面中,为什么我必须一遍又一遍地重新初始化它。有人建议使用突变观察者,但这感觉不对,我使用的 nextjs 不应该是一个 spa 并且只需要初始化一次。

我在预行中使用下拉组件。这是典型的模式还是我做错了什么?


// utils/preline.ts

let prelineInitialized = false;

export const initPreline = () => {
  if (typeof window === 'undefined' || prelineInitialized) return;

  import('preline/preline').then(({ HSDropdown }) => {
    const initDropdowns = () => {
      document.querySelectorAll('.hs-dropdown').forEach(el => {
        if (!el.classList.contains('hs-dropdown-initialized')) {
          new HSDropdown(el);
          el.classList.add('hs-dropdown-initialized');
        }
      });
    };

    // Initial initialization
    initDropdowns();

    // Set up MutationObserver to watch for new dropdowns
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (mutation.type === 'childList') {
          mutation.addedNodes.forEach((node) => {
            if (node instanceof HTMLElement) {
              if (node.classList.contains('hs-dropdown') && !node.classList.contains('hs-dropdown-initialized')) {
                new HSDropdown(node);
                node.classList.add('hs-dropdown-initialized');
              } else {
                node.querySelectorAll('.hs-dropdown:not(.hs-dropdown-initialized)').forEach(el => {
                  new HSDropdown(el);
                  el.classList.add('hs-dropdown-initialized');
                });
              }
            }
          });
        }
      });
    });

    observer.observe(document.body, { childList: true, subtree: true });

    prelineInitialized = true;
  });
};


reactjs next.js components tailwind-css
1个回答
0
投票

这可能不是解决方案,但可能会有所帮助。我也经历过类似的情况。让我解释一下我正在做什么来解决这个问题。

我正在使用 Preline HS 覆盖,我遇到了与您描述的完全相同的问题。

export default function Modal({
    id,
    title,
    close = true,
    width = "sm:max-w-lg",
    content,
    colophon,
}: Props) {
    const session = useAuth((state) => state.session);

    useEffect(() => {
        const id = setTimeout(() => window.HSOverlay.autoInit(), 2000);
        return () => clearTimeout(id);
    }, [session]);

    /**
     * Get class names for modal inner content.
     *
     * @returns {string} - The class names.
     * @since 1.0.0
     */
    const entryClass = (): string => {
        return mc(
            `modalInner hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 mt-8 mb-8 opacity-0 ease-out transition-all sm:w-full m-3 sm:mx-auto h-full flex items-center overflow-hidden relative ${width}`
        );
    };

    return (
        <div
            id={id}
            className="modalWrapper hidden hs-overlay backdrop-blur-sm hs-overlay-backdrop-open:bg-white/[0.5] dark:hs-overlay-backdrop-open:bg-zinc-950/[0.9] size-full fixed top-0 start-0 z-[80] overflow-hidden"
        >
            <div className={entryClass()}>
                <div className="flex flex-col w-full bg-white border border-gray-200 rounded-2xl shadow-lg overflow-hidden dark:bg-zinc-950 dark:border-zinc-800">
                    <Header id={id} title={title} close={close} />
                    <Content>{content}</Content>
                    {colophon && <Colophon>{colophon}</Colophon>}
                </div>
            </div>
        </div>
    );
}

我注意到当组件动态/有条件渲染时,我需要调用

autoinit()
静态方法。看看
useEffect

useEffect(() => {
    const id = setTimeout(() => window.HSOverlay.autoInit(), 2000);
    return () => clearTimeout(id);
}, [session]);

HS 选项卡的另一个示例。

const Navigation = () => {
    const session = useAuth((state) => state.session);

    useEffect(() => {
        const id = setTimeout(() => window.HSTabs.autoInit(), 2000);
        return () => clearTimeout(id);
    }, [session]);

    /**
     * Get tab nav item css class names.
     *
     * @returns {string} The tab nav item css class names.
     * @since 1.0.0
     */
    const navClass = (): string => {
        return "hs-tab-active:border-blue-500 hs-tab-active:text-blue-600 p-0 pe-10 inline-flex items-center gap-x-2 border-e border-transparent text-md whitespace-nowrap text-gray-600 hover:text-blue-600 focus:outline-none focus:text-blue-600 disabled:opacity-50 disabled:pointer-events-none dark:text-gray-200 dark:hover:text-blue-400 hs-tab-active:dark:border-blue-400 dark:focus:text-blue-400 transition-colors ease-in duration-300";
    };

    /**
     * Define tab nav items.
     *
     * @since 1.0.0
     */
    const nav = [
        {
            label: "Account",
            class: navClass() + " active",
            id: "#tabContentAccount",
            icon: "account",
        },
        {
            label: "Preferences",
            class: navClass(),
            id: "#tabContentPreferences",
            icon: "settings",
        },
    ];

    return (
        <div className="flex flex-col flex-shrink-0 relative border-e border-gray-100 dark:border-zinc-800">
            <nav
                className="flex flex-col gap-6"
                aria-label="Tabs"
                role="tablist"
                data-hs-tabs-vertical="true"
            >
                {nav.map((item, index) => (
                    <button
                        key={index}
                        type="button"
                        className={item.class}
                        data-hs-tab={item.id}
                        aria-controls={item.id.replace("#", "")}
                        role="tab"
                    >
                        {item?.icon === "account" ? (
                            <IconSticker clasX="size-6" />
                        ) : (
                            <IconSettings name="type-2" clasX="size-6" />
                        )}
                        {item.label}
                    </button>
                ))}
            </nav>
        </div>
    );
};

再次注意到我正在使用

window.HSTabs.autoInit();
方法。

希望这有帮助。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.