question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

bug: react, error when dismissing inline popover after removing containing element

See original GitHub issue

Prerequisites

Ionic Framework Version

  • v4.x
  • v5.x
  • v6.x

Current Behavior

When using IonReorderGroup with React.Fragment with multiple children, the number of from and to is higher then expected.

Expected Behavior

Should calculate by the number of IonReorder element, or by the number of children that IonReorderGroup had (treat Fragment as one child).

Steps to Reproduce

From the docs

const items = [1, 2, 3]
function doReorder(event) {
  // The number that printed is wrong and not following the number of the `IonReorder` elements
  console.log('Dragged from index', event.detail.from, 'to', event.detail.to)
  event.detail.complete()
}
<IonReorderGroup disabled={false} onIonItemReorder={doReorder}>
 {items.map((item) => <Fragment key={item}>
    <IonItem>
     <IonLabel>Item {item}</IonLabel>
     <IonReorder slot="end" />
    </IonItem>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
   </Fragment>)}
</IonReorderGroup>

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
amandaejohnstoncommented, Dec 17, 2021

Thanks! I’m able to reproduce the error. When a popover is opened, it is moved to the bottom of the ion-app. The error happens when Ionic tries to move the popover back to its original place, which in this case no longer exists. While a core JS popover fails gracefully, React errors out.

A possible fix would be if the popover could detect that its original location has been removed, and automatically dismiss itself. We’ll investigate this as a team and let you know when we have more to share.

In the meantime, a workaround would be to use the useIonPopover hook outside the Item component. This avoids both the error on dismiss (because the hook simply adds and removes the popover from the DOM, rather than moving it around), and the popover not closing (because its state is managed outside the removed Item). Here’s a code snippet putting both this and the IonReorderGroup together:

import { IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonPage, IonReorder, IonReorderGroup, IonTitle, IonToolbar, useIonPopover } from '@ionic/react';
import { ellipsisVertical } from 'ionicons/icons'
import { useState } from 'react';

const Home: React.FC = () => {
  const [items, setItems] = useState([1, 2, 3, 4, 5]);
  const [itemToRemove, setItemToRemove] = useState(null);
  const handlePresent = (data) => present(data);
  const handleDismiss = () => dismiss();
  const [present, dismiss] = useIonPopover(Popover, { setItems, itemToRemove, handleDismiss });

  function doReorder(event) {
    console.log('Dragged from index', event.detail.from, 'to', event.detail.to)
    event.detail.complete()
  }

  return (
    <IonPage>
      <IonContent>        
        <IonReorderGroup disabled={false} onIonItemReorder={doReorder}>
          { items.map(item => <Item key={item} item={item} setItemToRemove={setItemToRemove} handlePresent={handlePresent} />) }
        </IonReorderGroup>
      </IonContent>
    </IonPage>
  );
};

const Item = ({ item, setItemToRemove, handlePresent }) => {  
  return <IonItem>
    item {item}
    <IonButtons slot="end">
      <IonButton onClick={(e) => {
        setItemToRemove(item);
        handlePresent({ event: e.nativeEvent });
      }}>
        <IonIcon icon={ellipsisVertical} slot="icon-only" />
      </IonButton>
      <IonReorder />
    </IonButtons>
  </IonItem>
}

const Popover = ({ setItems, itemToRemove, handleDismiss }) => {
  return (
    <IonItem onClick={() => {
      handleDismiss();
      setItems((items) => items.filter((i) => itemToRemove !== i));
    }} button>
      remove
    </IonItem>
  )
}

export default Home;

0reactions
ionitron-bot[bot]commented, Feb 11, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to close an IonPopover in Ionic/React? - Stack Overflow
It works perfectly, the popover is shown and I can do something with it but I can only close it when I click...
Read more >
How to Dismiss a React-Bootstrap Popover on Click Outside
Another method to dismiss the popover is by using a different trigger event. You can use the hover or focus trigger instead of...
Read more >
How to Customise Ionic 6 Modal and Popover - YouTube
In Ionic 6 the styling of modals and popovers has changed, because they are now using Shadow DOM. Follow this quick win to...
Read more >
ion-popover - Ionic Framework
When using ion-popover with Angular, React, or Vue, the component you pass in will be destroyed when the popover is dismissed. As this...
Read more >
Transactional modal - Carbon Design System
Modal dialogs are commonly used to report system errors or convey a ... open with the entry marked in an error state and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found