Ionic не может прочитать свойства null (чтение ‘removeChild’) на странице StackManager.transitionPage

#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() может привести к этой ошибке.