【问题标题】:Pages are reloaded instead of routed in shopify next js app在 shopify next js 应用程序中重新加载页面而不是路由
【发布时间】:2020-12-07 08:34:44
【问题描述】:

我跟着Shopify's guide,直到第四步结束,开发了一个 Next JS 应用程序,我设置了两个页面(嵌入式应用程序导航),主页和 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>
    );
}

【问题讨论】:

    标签: reactjs next.js shopify-app next-router shopify-app-bridge


    【解决方案1】:

    使用 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>
    

    当 _app 加载时,它现在将订阅来自 appBridge 的更改,并让 appBridge 知道向客户端发送信号,而不是重新加载整个 iframe。如果您在应用程序中应用任何路由,例如一个页面到另一个页面,它现在也会更新浏览器的地址栏。

    【讨论】:

    • 谢谢德鲁!这就是我需要的东西,稍作修正:Route Propagator 现在是 @shopify/app-bridge-react 的一部分。
    【解决方案2】:

    一切正常,每次请求新的nextjs 页面时,您都会加载整个页面。为了在页面加载之间保持部分布局,您需要将它们移动到_app.js。 看看官方dynamic app layout example

    如果您想加载页面的子部分而不重新加载整个页面,您可以将queryshallow routing 结合使用,例如example.com/settingsexample.com/settings?section='profile'

    【讨论】:

    • 感谢 Ivan,但我应该如何通过不每次都加载整个页面来解决这个问题?有办法吗?
    猜你喜欢
    • 2018-07-04
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2018-05-24
    • 2017-09-11
    • 1970-01-01
    • 2022-08-04
    相关资源
    最近更新 更多