You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Shopify Polaris的SubNavigationItem点击时页面重载?

Shopify Polaris子导航点击页面重载问题解决方法

问题原因

SubNavigationItem的url属性会渲染原生<a>标签,点击时触发浏览器默认跳转逻辑,导致页面重载;而普通导航项你通过自定义onClick调用navigate,走的是React Router客户端路由,所以无重载问题。Polaris的SubNavigationItem不支持单独传入onClick,但可以通过Navigation组件的全局回调拦截所有导航行为。

解决方案

给Navigation组件添加onNavigationAction回调,拦截默认跳转行为,改用React Router的navigate处理路由;同时统一子导航项的路径格式,修正激活状态判断逻辑。

修改后的完整代码

import { Navigation } from '@shopify/polaris';
import './SettingsNavbar.scss';
import React, { useCallback, useEffect, useState } from 'react';
import {
  CreditCardMajor,
  CashDollarMajor,
  ToolsMajor,
  LogoBlockMajor,
  DiscountsMajor,
  CartMajor,
  CodeMajor,
  AffiliateMajor,
} from '@shopify/polaris-icons';
import { useLocation, useNavigate } from 'react-router-dom';

const tabs = ["general",'subscription','dynamic-pricing', "building-blocks", "shopify-discount-codes", 'checkout-options',"assets", "integrations"];

export const SettingsNavbar: React.FC = () => {
  const location = useLocation();
  const navigate = useNavigate();
  const [activeSettingsPage, setActiveSettingsPage] = useState('');

  // 拦截所有导航行为,改用React Router跳转
  const handleNavigationAction = useCallback((action) => {
    // 阻止浏览器默认跳转
    action.preventDefault();
    // 获取目标路径
    const targetPath = action.url;
    if (targetPath) {
      navigate(targetPath);
    }
  }, [navigate]);

  const handleNavItemClick = useCallback(
    (tabTitle: string, path?: string) => {
      if (path) {
        navigate(`/settings/${path}`);
      }
    },
    [navigate]
  );

  useEffect(()=>{
    const active = tabs.find((el)=>location.pathname.includes(el))
    setActiveSettingsPage(active || '')
  },[location.pathname])

  return (
    <div className='SettingsNavBar'>
      {/* 添加onNavigationAction回调拦截跳转 */}
      <Navigation location={location.pathname} onNavigationAction={handleNavigationAction}>
        <Navigation.Section
          items={[
            {
              onClick: () => handleNavItemClick('general', 'general'),
              selected: activeSettingsPage === 'general',
              label: 'General settings',
              icon: ToolsMajor,
            },
            {
              url: '/settings/building-blocks/sticky-bar',
              selected: activeSettingsPage === 'building-blocks',
              label: 'Building blocks',
              icon: LogoBlockMajor,
              subNavigationItems: [
                {
                  url: '/settings/building-blocks/sticky-bar',
                  disabled: false,
                  label: 'Sticky bar',
                  // 子项选中状态判断:当前路径匹配该子项url
                  selected: location.pathname === '/settings/building-blocks/sticky-bar'
                },
                {
                  url: '/settings/building-blocks/notification',
                  disabled: false,
                  label: 'Notification',
                  selected: location.pathname === '/settings/building-blocks/notification'
                },
                {
                  url: '/settings/building-blocks/collection-badge',
                  disabled: false,
                  label: 'Collection badge',
                  selected: location.pathname === '/settings/building-blocks/collection-badge'
                },
                {
                  url: '/settings/building-blocks/product-page-banner',
                  disabled: false,
                  label: 'Product page banner',
                  selected: location.pathname === '/settings/building-blocks/product-page-banner'
                },
                {
                  url: '/settings/building-blocks/countdown-clock',
                  disabled: false,
                  label: 'Countdown clock',
                  selected: location.pathname === '/settings/building-blocks/countdown-clock'
                },
                {
                  url: '/settings/cart-promotion-code-field',
                  disabled: false,
                  label: 'Cart promotion code field',
                  selected: location.pathname === '/settings/cart-promotion-code-field'
                },
                {
                  url: '/settings/cart-promotion-summary',
                  disabled: false,
                  label: 'Cart promotion summary',
                  selected: location.pathname === '/settings/cart-promotion-summary'
                },
              ],
            },
          ]}
        />
      </Navigation>
    </div>
  );
};

关键修改点说明

  1. 添加全局导航拦截:通过Navigation的onNavigationAction回调,调用action.preventDefault()阻止默认跳转,然后用navigate处理路由,实现客户端无刷新跳转。
  2. 统一子导航路径:修正部分子项缺失/settings前缀的问题,确保路径与React Router配置一致。
  3. 子项激活状态:给每个SubNavigationItem添加selected属性,根据当前路径精确匹配,确保选中状态正确。

内容的提问来源于stack exchange,提问作者Andriy Yurchuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 02:17:49