#cordova #ionic-framework #cordova-plugins #capacitor #ionic-react
Вопрос:
Я начал получать следующую ошибку при открытии приложения во время разработки (тоже после сборки/подписи).
Я думаю, что это что-то с Маршрутами, и я думаю, что я делаю что-то не так, как должно быть
Приложение в основном представляет собой что-то вроде крипто-кошелька с цифровой идентификацией, но не для криптографии, а для нашей компании. У меня есть еще несколько проблем, но это другая тема. :смайлик:
индекс.tsx
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import { AuthProvider } from "./contexts";
import App from "./App";
import "./i18n";
ReactDOM.render(
<React.StrictMode>
<Suspense fallback={<p>Loading...</p>}>
<Router>
<AuthProvider>
<App />
</AuthProvider>
</Router>
</Suspense>
</React.StrictMode>,
document.getElementById("root"),
);
Приложение.tsx
import { initChain } from "src/chain";
import { useAuth } from "src/contexts";
import { useBiometric } from "src/hooks";
import AppUrlListener from "src/components/AppUrlListener";
import NotificationsListener from "src/components/NotificationsListener";
import SecuritySettingsPage from "src/pages/SecuritySettings";
import SettingsPage from "src/pages/Settings";
import ScannerPage from "src/pages/Scanner";
import ProfilePage from "src/pages/Profile";
import BackupPage from "src/pages/Backup";
import ActionPage from "src/pages/Action";
import IntroPage from "src/pages/Intro";
import AboutPage from "src/pages/About";
import "src/vendor";
const App: React.FC = () => {
const { t } = useTranslation();
const { hasIdentity, identity } = useAuth();
const { checkBiometric } = useBiometric();
useEffect(() => {
if (!hasIdentity) return;
initChain();
checkBiometric();
}, [checkBiometric, hasIdentity]);
return (
<IonApp>
<IonReactRouter>
{!hasIdentity ? (
<IonRouterOutlet id="base">
<Route exact path="/intro" render={() => <IntroPage />} />
<Route exact render={() => <Redirect from="/" to="/intro" />} />
</IonRouterOutlet>
) : (
<>
<AppUrlListener />
<NotificationsListener />
<IonTabs>
<IonRouterOutlet id="main">
<Route exact path="/action" component={ActionPage} />
<Route exact path="/profile" component={ProfilePage} />
<Route exact path="/scanner" component={ScannerPage} />
<Route exact path="/settings" component={SettingsPage} />
<Route
exact
path="/settings/security"
component={SecuritySettingsPage}
/>
<Route exact path="/settings/about" component={AboutPage} />
<Route exact path="/settings/backup" component={BackupPage} />
<Route
exact
render={() => <Redirect push from="/" to="/profile" />}
/>
</IonRouterOutlet>
<IonTabBar slot="bottom" color="primary">
<IonTabButton layout="icon-top" tab="profile" href="/profile">
<IonIcon icon={personCircleOutline} />
<IonLabel>{t("Profile")}</IonLabel>
</IonTabButton>
<IonTabButton layout="icon-top" tab="scanner" href="/scanner">
<IonIcon icon={scanOutline} />
<IonLabel>{t("Scan")}</IonLabel>
</IonTabButton>
<IonTabButton layout="icon-top" tab="settings" href="/settings">
<IonIcon icon={settingsOutline} />
<IonLabel>{t("Settings")}</IonLabel>
{!identity?.hasBackup amp;amp; (
<IonBadge color="danger">
<IonIcon icon={alertOutline} />
</IonBadge>
)}
</IonTabButton>
</IonTabBar>
</IonTabs>
</>
)}
</IonReactRouter>
</IonApp>
);
};
{
"dependencies": {
"@capacitor/android": "3.2.2",
"@capacitor/app": "1.0.3",
"@capacitor/core": "3.2.2",
"@capacitor/haptics": "1.0.3",
"@capacitor/ios": "^3.2.2",
"@capacitor/keyboard": "1.0.3",
"@capacitor/network": "^1.0.3",
"@capacitor/push-notifications": "^1.0.4",
"@capacitor/status-bar": "1.0.3",
"@ionic-native/fingerprint-aio": "^5.36.0",
"@ionic-native/native-storage": "^5.36.0",
"@ionic-native/qr-scanner": "^5.36.0",
"@ionic-native/social-sharing": "^5.36.0",
"@ionic/react": "^5.7.0",
"@ionic/react-router": "^5.7.0",
"@ionic/storage": "^3.0.6",
"aes256": "^1.1.0",
"cordova-plugin-fingerprint-aio": "^4.0.2",
"cordova-plugin-nativestorage": "^2.3.2",
"cordova-plugin-qrscanner": "^3.0.1",
"cordova-plugin-x-socialsharing": "^6.0.3",
"es6-promise-plugin": "^4.2.2",
"i18next": "^20.4.0",
"i18next-resources-to-backend": "^1.0.0",
"ionicons": "^5.4.0",
"jetifier": "^2.0.0",
"node-sass": "^6.0.1",
"react": "^17.0.1",
"react-circular-progressbar": "^2.0.4",
"react-dom": "^17.0.1",
"react-hook-form": "^7.15.0",
"react-i18next": "^11.11.4",
"react-router": "^5.2.1",
"react-router-dom": "^5.3.0",
"react-scripts": "4.0.3",
"recheck-clientjs-library": "^1.0.23-beta.1",
"swiper": "^6.8.4"
},
"devDependencies": {
"@capacitor/cli": "3.1.2",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.6.3",
"@types/jest": "^26.0.20",
"@types/node": "^12.19.15",
"@types/react": "^16.14.3",
"@types/react-dom": "^16.9.10",
"@types/react-router": "^5.1.11",
"@types/react-router-dom": "^5.1.7",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-json": "^3.0.0",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"prettier": "^2.3.2",
"prettier-eslint": "^13.0.0",
"typescript": "^4.1.3"
}
}
Ionic:
Ionic CLI : 6.17.0 (/Users/byurhanbeyzat/.nvm/versions/node/v16.3.0/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/react 5.7.0
Capacitor:
Capacitor CLI : 3.1.2
@capacitor/android : 3.2.2
@capacitor/core : 3.2.2
@capacitor/ios : 3.2.2
Utility:
cordova-res : not installed globally
native-run (update available: 1.4.1) : 1.4.0
System:
NodeJS : v16.3.0 (/Users/byurhanbeyzat/.nvm/versions/node/v16.3.0/bin/node)
npm : 7.21.1
OS : macOS Big Sur
Заранее спасибо! :slight_smile:
Ответ №1:
Я получил ту же ошибку в ионной реакции:
Ionic не может прочитать свойства null (чтение ‘removeChild’) на странице StackManager.transitionPage
Эту ошибку было действительно трудно отследить, поэтому я делюсь тем, как я решил ее в своем конкретном случае.
Я храню объект пользователя в useReducer()
крючке и использую react-запрос для обработки выборки данных.
На одной странице с формой пользователя у меня был react-запрос с побочным эффектом, когда пользователь сохраняет форму, перенаправляет пользователя на новую страницу и обновляет локально сохраненный объект пользователя на основе ответа сервера:
onSuccess: async (response) => {
// Redirect must precede userDispatch to avoid unmounted component error.
history.push(routeSetupNextPage);
userDispatch({ type: 'updateStuff', payload: response });
},
На странице, на которую я перенаправил ( routeSetupNextPage
), я позвонил useIonViewDidEnter()
.
Эта комбинация обновления состояния объекта пользователя, которая вызвала пару повторных отрисовок, и history.push()
перенаправление на <IonPage>
компонент с useIonViewDidEnter()
тремя повторными отрисовками, третья из которых привела к ошибке: Ionic Cannot read properties of null (reading 'removeChild') at StackManager.transitionPage
.
В моем случае я исправил это, не вызывая userDispatch()
onSuccess()
; дело в том, что слишком много перерисовок при переходе на страницу с useIonDidEnter()
этой ошибкой типа или useIonViewWillEnter()
может привести к этой ошибке.