从网上找到的结果大多数是说如下情况:

错误:Super expression must either be null or a function, not undefined

或者错误:Uncaught (in promise) TypeError: Super expression must either be null or a function

一般是 React.Component 的引用和书写错误

import React, { Component } from 'react';

export default class App extends Component {} // 这里可能拼写错误或者引用错误

但是,我碰到的不是因为拼写错误的原因:

由于我的组件都继承自基类BaseScene,基类import进了一个js路由文件routerConfig进行遍历,由于外层路由文件的引用方式是采用的module.exports,它的对应引入方式是require('./app/src/page/...'),而基类采用了import进行引入,因此会报错,又由于require方式引入的只能是静态编译后的程序,而不能是运行时,所以导致了我的路由文件无法通过代码import其他子路由文件进入index.route.js主路由文件进行...解构,因此,我在使用路由文件的系统首文件index.js中,将const route = require('./app/router');方式改成了import route from './app/router';最终解决此问题。

完整代码如下:

基类:BaseScene.js

import { Alert } from 'react-native';
import React, { Component } from 'react';
import OAColor from '../theme/OAColor';
import { RunAfterInteractions } from '../utils';
import { IBText } from '../components/IBText';
import CommonSceneTools from '../widget/CommonSceneTools';
import { computeTraceCost } from '../common';
import { interfaceAdd } from '../services/system';
import routerConfig from '../../router';

export default class BaseScene extends Component<Props, State> {
  constructor(props) {
    super(props);
    mb(this).init(props, {
      startTime: Date.now()
    });
  }

  getName(obj) {
    if (obj && obj.props.metaType) {
      return obj.props.metaType;
    }
  }

  componentWillUnmount() {
    const name = this.getName(this); // 基类中获取当前调用基类的类的类名
    if (!name) return;
    const currConfig = routerConfig.find(route => route.name === name);
    const cost = computeTraceCost(this.state.startTime);
    if (currConfig && cost) {
      const title = currConfig.title;
      interfaceAdd(title, 'page', 'app', title, cost);
    }
  }

  /**
   * show nav title
   */
  showNavTitle(title: any, showback: boolean = true, defBg = OAColor.mainBg) {
    CommonSceneTools._setNavBottomBorder(this);
    mb(this).setNavBackgroundColor(defBg);
    mb(this).showNav();
    if (showback)
      // back press
      CommonSceneTools._setNavBackButton(this, () => {
        mb(this)
          .getNavigator()
          .pop();
      });
    mb(this).setNavTitle(title);
  }

  /**
   * show custom nav title
   */
  showNavTitleCustom(
    title: any,
    backButtonCallBack?: Function,
    rightBtnOptions?: { text?: string, color?: string, onPress?: Function }
  ) {
    CommonSceneTools._setNavBottomBorder(this);
    mb(this).setNavBackgroundColor(OAColor.mainBg);
    mb(this).showNav();
    CommonSceneTools._setNavBackButton(this, () => {
      backButtonCallBack
        ? backButtonCallBack()
        : mb(this)
            .getNavigator()
            .pop();
    });
    mb(this).setNavRightButton({
      type: 'standard',
      text: (
        <IBText color={rightBtnOptions.color || OAColor.txAccent} size={15}>
          {rightBtnOptions.text || '提交'}
        </IBText>
      ),
      onPress: () => {
        rightBtnOptions.onPress && rightBtnOptions.onPress();
      }
    });
    mb(this).setNavTitle(title);
  }

  /**
   * show right nav
   * declare callback
   */
  showNavRight(title: string, callback = void 0) {
    CommonSceneTools._setNavRightTextButton(this, title, callback);
  }

  /**
   * show right icon
   */
  showNavRightIcon(icon: any, callback = void 0) {
    CommonSceneTools._setNavRightIconButton(this, icon, callback);
  }

  /**
   * 跳转指定 scene and param
   */
  redirectTo(intent: string, param: any = {}) {
    // navigator
    if (!!intent) {
      mb.getNavigator().push(intent, param);
    } else {
      Alert.alert('invalid intent');
    }
  }

  /**
   * on load
   */
  executeOnLoad(action: Function = {}) {
    RunAfterInteractions(action);
  }

  /**
   * mb 方式更换 props
   */
  changeProps(props: any = {}) {
    mb(this).setProps(props);
  }
}

 

引入路由的系统首文件index.js

import { AppRegistry } from 'react-native';
import {
  setJSExceptionHandler,
  setNativeExceptionHandler
} from 'react-native-exception-handler';
import Entry from './Entry';
import Env from './env.json';
import Config from './config';
import route from './app/router';

console.disableYellowBox = true;

var SceneElement = require('./Components/SceneElement');
var ReaderLoading = require('./Components/Reader/ReaderLoading');
var StoreNavigator = require('./Components/Store/StoreNavigator');
var StorePhotoGallery = require('./Components/Store/StorePhotoGallery');
var StoreImageViewer = require('./Components/Store/StoreImageViewer');
var StoreExternalURL = require('./Components/Store/StoreExternalURL');

global.refs = {
  SceneElement: SceneElement,
  ReaderLoading: ReaderLoading,
  StoreNavigator: StoreNavigator,
  StorePhotoGallery: StorePhotoGallery,
  StoreImageViewer: StoreImageViewer,
  StoreExternalURL: StoreExternalURL
};

// tab bar配置
global.tabBarConfig = {};

global.topCompleteStruct = require('./store');

// const route = require('./route');
// const route = require('./app/router');

route.forEach((r, k) => {
  global.refs[r.name] = r.component;

  let newItem = {
    name: r.name,
    metaType: 'SceneElement',
    switchType: 'PushFromRight',
    barStyle: 'default',
    key: 'Scene' + r.name,
    style: {
      color: '#000',
      backgroundColor: 'transparent'
    },
    items: [
      {
        name: 'Component' + r.name,
        metaType: r.name,
        key: 'Component' + r.name
      }
    ]
  };

  if (r.nav) {
    newItem = { ...newItem, ...r.nav };
  }

  global.topCompleteStruct.items[0].items.push(newItem);

  if (k == 0 || r.isHome) {
    global.topCompleteStruct.items[0].initComponentName = r.name;
  }
});

global.shellSceneNum = global.topCompleteStruct.items[0].items.length;
global.shellSceneNumOrigin = global.topCompleteStruct.items[0].items.length;
global.routeStack = [];
global.pushingLock = false;
global.notTouchable = false;
global.routeRef = {};
global.navBarConfig = require('./Components/navbar.config');
global.statusBarConfig = Config.statusBar || {};
global.Zqmb = require('./zqmb');

require('./Components/Mobile');

Zqmb.loginForSystem(Env.SYSTEM_ENTRY, 'admin', '753951', '', '')
  .then(r => {
    if (!mb.isSubProject()) {
      mb.silentUpdate();
    }
  })
  .catch(e => {});

/*错误上报*/
if (mb.isSubProject()) {
  setJSExceptionHandler((e, isFatal) => {
    if (e) {
      mb.getMainProjectParams().then(res => {
        const { SYSTEM_HOST, PROJECT_ID, SYSTEM_ENTRY } = res;
        Zqmb.me()
          .setDomain(SYSTEM_HOST) // 主应用SYSTEM_HOST
          .get(
            '/' + SYSTEM_ENTRY + '/inspector/createAppError',
            JSON.stringify({
              userId: mb.getUserId(),
              deviceName: mb.device.getDeviceName(),
              systemName: mb.device.getSystemName(),
              systemVersion: mb.device.getSystemVersion(),
              appVersion: mb.device.getVersion(),
              projectId: PROJECT_ID,
              type: 1,
              detail: `IsFatal: ${isFatal ? 'true' : 'false'}
    Name: ${e.name}
    Page: ${global.currentRouteName}
    Message: ${e.message}
    `
            }).replace(/\"/g, '\\"')
          )
          .then(r => r.text())
          .then(r => {
            if (isFatal) {
              mb.alert('应用出错', '相关错误将会被尽快处理', [
                {
                  text: '确认',
                  onPress: () => {
                    // mb.reloadApp();
                    mb.quitSubProject();
                  }
                }
              ]);
            }
          });
      });
    }
  });

  setNativeExceptionHandler(exceptionString => {
    if (exceptionString) {
      mb.getMainProjectParams().then(res => {
        const { SYSTEM_HOST, PROJECT_ID, SYSTEM_ENTRY } = res;
        Zqmb.me()
          .setDomain(SYSTEM_HOST) // 主应用SYSTEM_HOST
          .get(
            '/' + SYSTEM_ENTRY + '/inspector/createAppError',
            JSON.stringify({
              userId: mb.getUserId(),
              deviceName: mb.device.getDeviceName(),
              systemName: mb.device.getSystemName(),
              systemVersion: mb.device.getSystemVersion(),
              appVersion: mb.device.getVersion(),
              projectId: PROJECT_ID,
              type: 2,
              detail: `Page: ${global.currentRouteName}
    Message: ${exceptionString}
    `
            }).replace(/\"/g, '\\"')
          )
          .then(r => r.text())
          .then(r => {
            mb.alert('应用出错', '相关错误将会被尽快处理', [
              {
                text: '确认'
              }
            ]);
          });
      });
    }
  });
}

AppRegistry.registerComponent('mbstore_shell_base', () => Entry);

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐