离子无法在 StackManager.transitionPage 读取 null 的属性(读取“removeChild”)

Posted

技术标签:

【中文标题】离子无法在 StackManager.transitionPage 读取 null 的属性(读取“removeChild”)【英文标题】:Ionic Cannot read properties of null (reading 'removeChild') at StackManager.transitionPage 【发布时间】:2021-11-05 12:51:42 【问题描述】:

我开始在开发时打开应用程序时出现下一个错误(在构建/签名后也有)

我认为这是路线的问题,我认为我没有做一些事情,因为它必须是

该应用程序基本上类似于具有数字身份的加密钱包,但不适用于加密货币,它适用于我们公司。 我还有一些问题,但它们是不同的主题。 :笑脸:

index.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"),
);

App.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 && (
                    <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 React 中遇到了同样的错误:

Ionic 无法读取 null 的属性(读取“removeChild”) StackManager.transitionPage

这是一个非常难以追踪的错误,因此我将分享我在特定情况下是如何解决它的。

我将用户对象存储在useReducer() 挂钩中,并使用react-query 处理我的数据获取。

在一个带有用户表单的页面上,我有一个带有副作用的 react-query,当用户保存表单时,将用户重定向到新页面并根据服务器更新本地存储的用户对象回复:

  onSuccess: async (response) => 
    // Redirect must precede userDispatch to avoid unmounted component error.
    history.push(routeSetupNextPage);
    userDispatch( type: 'updateStuff', payload: response );
  ,

在我重定向到的页面 (routeSetupNextPage) 上,我调用了useIonViewDidEnter()

这种更新用户对象状态的组合导致了几次重新渲染,以及history.push() 重定向到带有useIonViewDidEnter()&lt;IonPage&gt; 组件导致了三次重新渲染,其中第三次导致错误:Ionic Cannot read properties of null (reading 'removeChild') at StackManager.transitionPage

就我而言,我通过不在onSuccess() 中调用userDispatch() 来解决此问题;关键是在转换到带有useIonDidEnter()useIonViewWillEnter() 的页面时,过多的重新渲染可能会导致这种类型的错误。

【讨论】:

以上是关于离子无法在 StackManager.transitionPage 读取 null 的属性(读取“removeChild”)的主要内容,如果未能解决你的问题,请参考以下文章

离子 - XMLHttpRequest 无法加载

离子 ios 应用程序无法访问互联网

无法获得离子来构建android apk

离子 - 当标签 <form> 中有 *ngIf 时无法获取离子输入的值

无法在点击事件时设置离子本地通知(奇怪的语法错误)

无法在 Chimp 验收测试中单击离子侧菜单按钮