Join us for an upcoming Shopify Partner webinar on February 27, 2024. Discover the latest Checkout Extensibility features, and deep dive on improvements to Shopify Functions and Web Pixels. Register now for either the 10am EST or 2pm EST sessions.

@shopify/app-bridge-react bug with multiple modals

MarcBaumbach
Shopify Partner
32 0 15

Originally reported against the @shopify/polaris project on GitHub: https://github.com/Shopify/polaris-react/issues/2009

 

When using the Modal component from the app bridge react components in an embedded app, if you have multiple modals rendering it will always display the last modal in the component hierarchy even when specifying the open prop for any others.

 

No matter what Modal has the open prop set to true, the last modal rendered in the entire component hierarchy is the one that is displayed. This is true for components that are deeply nested too. You may change a prop on a Modal in a component based on local state and some other Modal in a disparate part of the component hierarchy will display if it's rendered later.

 

The following is a reduced test case that can be put into a create-react-app project with Polaris and app-bridge-react dependencies.

 

import React, { Component } from 'react';
import {
  AppProvider,
  Page,
  Layout,
  Button
} from '@shopify/polaris';
import {
  Provider,
  Modal
} from '@shopify/app-bridge-react';

const API_KEY = 'CHANGE_ME_1';
const SHOP_ORIGIN = 'CHANGE_ME_2';

export default class App extends Component {
  state = {
    showModal1: false,
    showModal2: false
  }
  
  render() {
    const { showModal1, showModal2 } = this.state;
    const config = {
      apiKey: API_KEY,
      shopOrigin: SHOP_ORIGIN,
      forceRedirect: true 
    };
    return (
      <AppProvider>
        <Provider config={config}>
          <Page>
            <Layout sectioned>
              <Button onClick={() => this.setState({ showModal1: true })} fullWidth>Display modal</Button>
            </Layout>
            <Modal
              title="Modal 1"
              message="Modal 1"
              onClose={() => this.setState({ showModal1: false })}
              open={showModal1} />
            <Modal
              title="Modal 2"
              message="Modal 2"
              onClose={() => this.setState({ showModal2: false })}
              open={showModal2} />
          </Page>
        </Provider>
      </AppProvider>
    );
  }
}

Clicking the Button sets the showModal1 state to true and should display "Modal 1" but "Modal 2" shows up instead. Conditionally rendering the modals does open the correct Modal, but closing them programmatically with the open prop isn't really possible unless you do it across two separate renders.

Reply 1 (1)

Josh
Shopify Staff
1134 84 233

Hey @MarcBaumbach , 

 

You reported this correctly, I reached out to someone on our team to have them respond so you can discuss the issue with them there. Best of luck! 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog