Shopify Next.js 应用程序中的页面被重新加载而不是路由。

6
我遵循Shopify的教程开发了一个Next JS应用程序,并设置了两个页面(内嵌应用程序导航)Home和Page1。但是,当我点击打开这两个页面时,应用程序会重新加载而不是路由...

您可以在此处查看闪烁问题 - https://youtu.be/45RvYgxC7C0

非常感谢任何对此的帮助。

_app.js

import React from "react";

import App from "next/app";
import Head from "next/head";

import { AppProvider } from "@shopify/polaris";
import { Provider } from "@shopify/app-bridge-react";
import Cookies from "js-cookie";

import "@shopify/polaris/dist/styles.css";
import "../css/styles.css";

import lang from "@shopify/polaris/locales/en.json";

export default class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props;
        const config = { apiKey: API_KEY, shopOrigin: Cookies.get("shopOrigin"), forceRedirect: true };

        return (
            <React.Fragment>
                <Head>
                    <title>My App</title>

                    <meta charSet="utf-8" />
                    <meta name="viewport" content="width=device-width, initial-scale=1" />

                    <link rel="icon" href="favicon.ico" />
                </Head>

                <Provider config={config}>
                    <AppProvider i18n={lang}>
                        <Component {...pageProps} />
                    </AppProvider>
                </Provider>
            </React.Fragment>
        );
    }
}

home.js

import React from "react";

import { Page, Layout, Card, FooterHelp, Link } from "@shopify/polaris";

export default function Home() {
    return (
        <Page title="Home">
            <Layout>
                <Layout.Section>
                    <Card title="Online store dashboard" sectioned>
                        <p>View a summary of your online store’s performance.</p>
                    </Card>
                </Layout.Section>

                <Layout.Section>
                    <FooterHelp>
                        Learn more about{" "}
                        <Link url="#" external>
                            our app
                        </Link>
                    </FooterHelp>
                </Layout.Section>
            </Layout>
        </Page>
    );
}

Page1.js

import React from "react";

import { Page, Layout, Card, FooterHelp, Link } from "@shopify/polaris";

export default function Page1() {
    return (
        <Page title="Page1">
            <Layout>
                <Layout.Section>
                    <Card title="Online store dashboard" sectioned>
                        <p>View a summary of your online store’s performance.</p>
                    </Card>
                </Layout.Section>

                <Layout.Section>
                    <FooterHelp>
                        Learn more about{" "}
                        <Link url="#" external>
                            our app
                        </Link>
                    </FooterHelp>
                </Layout.Section>
            </Layout>
        </Page>
    );
}
2个回答

10
使用Shopify的app-bridge时,它默认行为是在包含您的应用程序的iframe内导航到新路由(因此完全重新加载应用程序),而React实现了客户端路由。
Shopify没有为使用客户端路由提供100%即插即用的解决方案,但他们通过其ClientRouter组件使得这变得相当容易。 该页面上的示例适用于react-router,而不是Next.js的路由器,但同样的想法也适用于next/router。 例如,一个简单的路由器组件可能如下所示:
import {useEffect, useContext} from 'react';
import Router, { useRouter } from "next/router";
import { Context as AppBridgeContext } from "@shopify/app-bridge-react";
import { Redirect } from "@shopify/app-bridge/actions";
import { RoutePropagator as ShopifyRoutePropagator } from "@shopify/app-bridge-react";

const RoutePropagator = () => {
  const router = useRouter(); 
  const { route } = router;
  const appBridge = React.useContext(AppBridgeContext);

  // Subscribe to appBridge changes - captures appBridge urls 
  // and sends them to Next.js router. Use useEffect hook to 
  // load once when component mounted
  useEffect(() => {
    appBridge.subscribe(Redirect.Action.APP, ({ path }) => {
      Router.push(path);
    });
  }, []);

  return appBridge && route ? (
    <ShopifyRoutePropagator location={route} app={appBridge} />
  ) : null;
}

export default RoutePropagator;

创建组件后,将其放置在Shopify路由器内的_app.js文件中,例如:

<Provider config={config}>
  <AppProvider i18n={translations}>
    <RoutePropagator />
    <ApolloProvider client={client}>
      // child components
    </ApolloProvider>
  </AppProvider>
</Provider>
当应用程序加载时,它现在将订阅来自appBridge的更改,并告知appBridge发送信号到客户端,而不是重新加载整个iframe。如果您在应用程序中应用任何路由(例如从一页到另一页),它还将更新浏览器的地址栏。

2
谢谢Drew!这正是我需要的东西,只有一个小修正:Route Propagator现在是@shopify/app-bridge-react的一部分。 - Alexis
非常感谢!我的头都快要爆炸了.. 这让我朝着正确的方向去解决问题。 - typicalk
你好,@Alexis。你能提供你的代码让我们看看是怎么做出来的吗?这将非常不错! - Safety

0

一切正常,每次请求新的nextjs页面时,整个页面都会被加载。为了使你的布局在页面加载之间保持一致,你需要将它们移动到_app.js中。 可以查看官方动态应用程序布局示例进行参考。

如果您想要加载页面的子部分而不重新加载整个页面,则可以使用查询浅层路由相结合,例如example.com/settingsexample.com/settings?section='profile'


谢谢Ivan,但是我该如何在不每次加载整个页面的情况下修复它?有什么办法可以做到这一点吗? - Alexis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接