I’m trying to learn Ionic/React. I put Alan Montgomery’s (Does ionic/React content) Notes code into an app with IonTabs
. In other words, you can click on Notes and it goes to his code. My problem is whenever I try and navigate away from the Notes tab, I never really leave. IonViewDidLeave
never triggers! Yet somehow I see the code from the other tabs mounting. How do I make it so when I leave the Notes tab I really leave?
Here is Notes code (based on Alan’s):
import { IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCheckbox, IonCol, IonContent, IonFab, IonFabButton, IonGrid, IonHeader, IonIcon, IonItem, IonPage, IonRow, IonSlide, IonSlides, IonToolbar, useIonViewDidEnter,useIonViewDidLeave, useIonViewWillEnter, useIonViewWillLeave } from '@ionic/react';
import styles from './Notes.module.scss';
import React, { useEffect } from 'react';
import { addOutline, menuOutline, notificationsOutline, searchOutline } from "ionicons/icons";
import { getCategories, getNotes } from '../store/Selectors';
import { CategoryStore, NoteStore } from '../store';
import { markNote } from "../store/NoteStore";
const Notes = () => {
useEffect(() => {
console.log('Notes mounted');
return () => {
console.log('Notes unmounted');
}
},[]);
useIonViewDidEnter(() => {
console.log('ionViewDidEnter event fired');
});
useIonViewDidLeave(() => {
console.log('ionViewDidLeave event fired');
});
useIonViewWillEnter(() => {
console.log('ionViewWillEnter event fired');
});
useIonViewWillLeave(() => {
console.log('ionViewWillLeave event fired');
});
const categories = CategoryStore.useState(getCategories);
const notes = NoteStore.useState(getNotes);
const getNoteStyle = (categoryID, isComplete = false) => {
const categoryColor = categories.filter(category => category.id === categoryID)[0].color;
return {
"--background": categoryColor,
"--background-checked": categoryColor,
"--border-style": "none",
"opacity": isComplete ? "0.6" : "1"
}
}
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonButton>
<IonIcon icon={ menuOutline } />
</IonButton>
</IonButtons>
<IonButtons slot="end">
<IonButton>
<IonIcon icon={ searchOutline } />
</IonButton>
<IonButton>
<IonIcon icon={ notificationsOutline } />
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonGrid>
<IonRow>
<IonCol size="12" className="ion-padding-start">
<h1 className={ styles.mainTitle }>Hello, Alan!</h1>
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12" className="ion-padding-start ion-padding-top">
<IonCardSubtitle className={ styles.heading }>
Categories
</IonCardSubtitle>
</IonCol>
</IonRow>
</IonGrid>
<IonSlides id="slider" options={{ slidesPerView: "auto", zoom: true, grabCursor: true }} className={ `${ styles.categorySlider } ion-padding-bottom` }>
{ categories.map((category, index) => {
const noteCount = notes.filter(n => n.category_id === category.id).length;
return (
<IonSlide key={ `categorySlide_${ index }`}>
<IonCol className="ion-text-left">
<IonCard>
<IonCardHeader className="ion-no-padding">
<div className={ styles.slideCount }>
<h6>{ noteCount } { noteCount === 1 ? "note" : "notes" } </h6>
</div>
<div className={ styles.slideHeader }>
<h4>{ category.name }</h4>
</div>
</IonCardHeader>
<IonCardContent>
<div className={ styles.categoryColor } style={{ borderBottom: `2px solid ${ category.color }` }}></div>
</IonCardContent>
</IonCard>
</IonCol>
</IonSlide>
);
})}
</IonSlides>
<IonGrid className={ styles.bottomContainer }>
<IonRow>
<IonCol size="12" className="ion-padding-start">
<IonCardSubtitle className={ styles.heading }>
Recent Notes
</IonCardSubtitle>
</IonCol>
</IonRow>
<div className={ styles.recentNotes }>
{ notes.map((note, index) => {
return (
<IonRow key={ `note_${ index }` } className="animate__animated animate__faster" id={ `noteRow_${ note.id }` }>
<IonCol size="12">
<IonItem>
<IonCheckbox checked={ note.complete } style={ getNoteStyle(note.category_id, note.complete) } onClick={ () => markNote(note.id) } />
<h4 style={ note.complete ? { textDecoration: "line-through", opacity: "0.6" } : {} }>{ note.note }</h4>
</IonItem>
</IonCol>
</IonRow>
);
})}
</div>
</IonGrid>
<IonFab vertical="bottom" horizontal="end" slot="fixed" className="ion-padding">
<IonFabButton routerLink="/add">
<IonIcon icon={ addOutline } />
</IonFabButton>
</IonFab>
</IonContent>
</IonPage>
);
};
export default Notes;
Here is app.js:
import { Redirect, Route } from 'react-router-dom';
import { IonApp, IonContent, IonRouterOutlet, IonTabButton, IonTabBar, IonLabel, IonIcon, IonTabs, IonPage } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import Map from './pages/Map';
import Notes from './pages/Notes';
import Add from './pages/Add';
import { triangle, ellipse, square } from 'ionicons/icons';
/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';
/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';
/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';
/* Theme variables */
import './theme/variables.css';
function test () {
return <div>hello</div>
}
//<Redirect from="/" to="/map"/>
function App () {
return (
<IonApp>
<IonReactRouter>
<IonTabs>
<IonRouterOutlet>
<Route path="/map" component={Map}/>
<Route path="/test" component={test}/>
<Route path="/notes" render={() => <Notes/>}/>
<Route path="/add" component={Add}/>
<Route exact path = '/' render={() => <Redirect to ="/map"/>}/>
</IonRouterOutlet>
<IonTabBar slot='bottom'>
<IonTabButton tab='Map' href='/map'>
<IonIcon icon={triangle} />
<IonLabel>Map</IonLabel>
</IonTabButton>
<IonTabButton tab='Notes' href='/notes'>
<IonIcon icon={square} />
<IonLabel>Notes</IonLabel>
</IonTabButton>
<IonTabButton tab='Test' href='/test'>
<IonIcon icon={square} />
<IonLabel>Test</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</IonReactRouter>
</IonApp>
);
}
export default App;
2 posts - 1 participant