I am using Ionic capacitor to build my reactjs Web application. I have added a Capacitor App Apis to get the back event capture in my App.js file like this,
APPS.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
But when i press back button this back event is called 3 times instead of one. my App.js file is.
// import "./StyleSeets/LightTheme.css";
import "./StyleSeets/theme.css";
import "./App.css";
import React, { useEffect, useState } from "react";
import Drawer from "@mui/material/Drawer";
import { App as APPS } from "@capacitor/app";
import Login from "./Components/Login";
import ERPUtils from "./Components/ERPUtils";
import Main from "./Components/Main";
// ************************** back fire event handling ****************
const renderedScreenUIList = [];
function App() {
// const [ stylePath, setStylePath ] = useState("./StyleSeets/LightTheme.css");
const [renderPageType, setRenderPageType] = useState("login");
const [isMobileView, setIMobileView] = useState(window.innerWidth < 920);
const isConsoleOpen = false;
window.onresize = function () {
console.log(window.outerHeight - window.innerHeight);
if ((window.outerHeight - window.innerHeight) > 100) { console.log("open"); } else console.log("close");
};
const themeList = [
{ value: "#2776ed", label: "light" },
{ value: "#45b11c", label: "nature" },
{ value: "#2AB67B", label: "evening" },
{ value: "#add8e6", label: "sky" },
{ value: "#2b035b", label: "dark" }];
const languageList = [
{ value: "ENG", label: "English" },
{ value: "MAL", label: "മലയാളം" },
{ value: "HIND", label: "हिन्दी" }];
const [language, setLanguage] = useState("ENG");
const onThemeChangeCall = () => {
const themeName = sessionStorage.getItem("theme-name");
const themeElement = document.getElementById("app-theme");
themeElement.className = "App";
document.documentElement.setAttribute("data-theme", themeName);
};
APPS.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
const languageChanged = (type) => {
setLanguage(type);
};
useEffect(() => {
onThemeChangeCall();
}, []);
const changePage = (page) => {
setRenderPageType(page);
};
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
const changeTheme = (type) => {
sessionStorage.setItem("theme-name", type);
document.documentElement.classList.add("color-theme-in-transition");
window.setTimeout(() => {
document.documentElement.classList.remove("color-theme-in-transition");
}, 1000);
onThemeChangeCall();
};
const toggleDrawer = (value) => {
setIsSettingsOpen(value);
};
const changeLanguage = (type) => {
sessionStorage.setItem("language-theme", type);
languageChanged(type);
};
useEffect(() => {
setIMobileView(window.innerWidth < 920);
}, [window.innerWidth]);
return (
<div className="App" id="app-theme">
{renderPageType === "login"
? (
<Login
onThemeChangeCall={onThemeChangeCall}
changePage={changePage}
languageChanged={languageChanged}
toggleDrawer={toggleDrawer}
/>
)
: null}
{renderPageType === "home"
? (
<Main
onThemeChangeCall={onThemeChangeCall}
changePage={changePage}
languageChanged={languageChanged}
toggleDrawer={toggleDrawer}
isMobileView={isMobileView}
/>
)
: null}
<Drawer
anchor="right"
open={isSettingsOpen}
onClose={() => toggleDrawer(false)}
>
<div className="p-2 " style={{ width: "250px", backgroundColor: "var(--primaryBackground)" }}>
<h6 className="border-bottom p-2">Themes</h6>
<div className="">
{!ERPUtils.isNullorWhiteSpace(themeList) ? themeList.map((el, index) => (
<div
key={index}
onKeyDown={(e) => {
if (ERPUtils.isKeyBoardEnterPressed(e)) {
changeTheme(el.label);
}
}}
role="button"
tabIndex={0}
className="p-2 d-flex align-items-center font-2 justify-content-start"
onClick={() => changeTheme(el.label)}
>
<span className="theme-thumbnail" style={{ backgroundColor: el.value }} />
<span>{(`${el.label}`).toLocaleUpperCase()}</span>
</div>
)) : null}
</div>
</div>
<div className="p-2" style={{ width: "250px", backgroundColor: "var(--primaryBackground)" }}>
<h6 className="border-bottom p-2">Language</h6>
<div className="">
{!ERPUtils.isNullorWhiteSpace(languageList) ? languageList.map((el, index) => (
<div
key={index}
onKeyDown={(e) => {
if (ERPUtils.isKeyBoardEnterPressed(e)) {
changeLanguage(el.value);
}
}}
role="button"
tabIndex={0}
className="p-2 d-flex align-items-center font-2 justify-content-start"
onClick={() => changeLanguage(el.value)}
>
<span className="language-thumbnail">{el?.label.split("")[0]}</span>
<span>{(`${el.label}`).toLocaleUpperCase()}</span>
</div>
)) : null}
</div>
</div>
</Drawer>
{/* <ThemeSwitcherProvider defaultTheme="light" themeMap={themes}> */}
{/* <link rel="stylesheet" type="text/css" href={stylePath} /> */}
{/* </ThemeSwitcherProvider> */}
</div>
);
}
export default App;
Kindly suggest a solution for this problem ?. If I call this event listener outside App.js file it only calls once.
CodePudding user response:
With each page reload the listener is added again. To fix this you should call removeAllListeners() => Promise<void>
once at the beginning:
App.removeAllListeners().then(() => {
App.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
});