【问题标题】:How do I route between pages in Embedded React App?如何在 Embedded React App 中的页面之间路由?
【发布时间】:2021-07-03 20:31:28
【问题描述】:

背景:

我正在尝试在我的嵌入式 Shopify 应用中创建一些链接。

我了解,由于 Shopify 嵌入式应用程序呈现为 iframe,我无法使用简单的 <a> 标签。

我在本教程中取得了一些进展,但我卡住了:https://theunlikelydeveloper.com/shopify-app-bridge-react-router/

我想做的事:

我有 3 个页面(index.js、dashboard.js 和 support.js)。我想允许用户从一个页面导航到另一个页面(使用链接和/或按钮)。

我的代码:

按照上面的教程,我已经做到了这一点:

// index.js
import { Page, Frame } from "@shopify/polaris";

const Index = () => {
  return (
    <Page>
      <Frame>
        {/* LINK TO DASHBOARD PAGE*/}
        {/* LINK TO SUPPORT PAGE */}
      </Frame>
    </Page>
  );
};

export default Index;
// routes.js
import React from "react";
import { Switch, Route, withRouter } from "react-router";
import { ClientRouter, RoutePropagator } from "@shopify/app-bridge-react";

function Routes(props) {
  const { history, location } = props;

  return (
    <>
      <ClientRouter history={history} />
      <RoutePropagator location={location} />
      <Switch>
        <Route path="/dashboard">
          <Dashboard />
        </Route>
        <Route path="/support">
          <Support />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </>
  );
}

export default withRouter(Routes);
// link.js
import React from "react";
import { Link as ReactRouterLink } from "react-router";

const IS_EXTERNAL_LINK_REGEX = /^(?:[a-z][a-z\d+.-]*:|\/\/)/;

function Link({ children, url = "", external, ref, ...rest }) {
  if (external || IS_EXTERNAL_LINK_REGEX.test(url)) {
    rest.target = "_blank";
    rest.rel = "noopener noreferrer";
    return (
      <a href={url} {...rest}>
        {children}
      </a>
    );
  }

  return (
    <ReactRouterLink to={url} {...rest}>
      {children}
    </ReactRouterLink>
  );
}

export default Link;

补充:

我相信我应该在某处实现以下代码,但我看不出它如何适合使用链接或按钮在页面之间导航的画面。

<AppProvider linkComponent={Link}>
  {/* App content including your <Route> components */}
</AppProvider>

【问题讨论】:

  • 看来您的Link 将替换之前从react-router 导入的所有Link 组件。
  • 谢谢,@DrewReese - 这是否意味着我需要在某处包含&lt;AppProvider linkComponent={Link}&gt;?如果是这样,我需要在里面放什么?
  • 另外,我尝试简单地将&lt;Link url="/dashboard"&gt;Go to Dashboard&lt;/Link&gt; 之类的内容添加到 index.js 中,但没有成功。有什么想法吗?
  • 您是否从'@shopify/polaris' 导入了AppProvider 并将您的代码包装在您的路由器中?另外,你在某处也有Router 组件吗?
  • 所以我假设我需要编辑我的 index.js 文件和 1) 导入 AppProvider,2) 包括上面的 linkComponent 代码,3) 创建某种路由器。我有一个从Shopify Docs 获得的 ClientRouter.js 组件。我在正确的轨道上吗?

标签: reactjs shopify-app


【解决方案1】:

在构建嵌入式应用程序时,您可以使用应用程序桥实用程序进行客户端导航,如 in this answer

您只需要编辑_app 文件并考虑从您的组件进行客户端导航(不能使用普通链接)


import {useEffect} from 'react';
import Router, { useRouter } from "next/router";
import { RoutePropagator as ShopifyRoutePropagator } from "@shopify/app-bridge-react";


function RoutePropagator () {
  const router = useRouter();
  const { route } = router;
  const app= useAppBridge();

  useEffect(() => {
    app.subscribe(Redirect.Action.APP, ({ path }) => {
      Router.push(path);
    });
  }, []);

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

然后在你的_app 文件中使用这个组件

_app.tsx


class MyApp extends App {

  render() {

    const { Component, pageProps, host } = this.props as any;

    return (
      <PolarisProvider i18n={translations}>

        <ShopifyBridgeProvider
          config={{
            apiKey: API_KEY,
              host,
              forceRedirect: true,
          }}
        >
          <RoutePropagator />
          <ApolloClientProvider Component={Component} {...pageProps} />

        </ShopifyBridgeProvider>

      </PolarisProvider>
    );
  }
}

现在您已经订阅了_app 文件中的路由事件,我们只需要在您的页面中进行客户端导航

import {useAppBridge} from '@shopify/app-bridge-react';
import  { Redirect } from '@shopify/app-bridge/actions';

function IndexPage(props) {

  const app = useAppBridge();

  return (
    <>
      <div>{'you are in main page'}</div>

      <div onClick={() => {
        app.dispatch(Redirect.toApp({
          path: '/dashboard'
        }));
      }}>
        {'to dashboard'}
      </div>
    </>
  );

}

对于返回主页/路由,我发现如果没有提供商店名称,它会再次触发oauth,因此我们将为此使用商店查询参数

 <div onClick={() => {
      app.dispatch(Redirect.toApp({
        path: '/?shop=<shop-name>.myshopify.com'
      }));
    }}>
      {'to main'}
 </div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2019-10-09
    • 2021-10-04
    • 2020-07-03
    • 1970-01-01
    • 2018-09-13
    • 2021-10-19
    相关资源
    最近更新 更多