避免 ReactJS 项目中“Office.js 尚未完全加载”错误的可靠方法

问题描述 投票:0回答:1

我们开发 Excel 插件。我们时不时地观察到这个

Error: Office.js has not fully loaded. Your app must call "Office.onReady()" as part of it's loading sequence (or set the "Office.initialize" function). If your app has this functionality, try reloading this page.
它看起来并不是很阻塞。但是,现在我们意识到,当 Mac for Excel 中发生这种情况时,任务窗格会变成空白页。用户必须再次重新加载页面才能看到此错误并正确加载页面。

因此我们希望找到一种稳健的方法来避免此错误。

我们的插件是用Reactjs和dva构建的,这是一个基于redux、redux-saga和react-router的框架。这是

frontend/src/index.tsx

import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import dva from 'dva';
import router from './router';
import AuthModel from './models/auth';
import SubscribtionModel from './models/subscription';
import AppModel from './models/app';
import SpreadsheetModel from './models/spreadsheet';
import UsageModel from './models/usage';
import SettingsModel from './models/settings';
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';

initializeIcons();

const app = dva();

app.model(AuthModel);
app.model(SubscribtionModel)
app.model(AppModel);
app.model(SpreadsheetModel);
app.model(UsageModel);
app.model(SettingsModel);

app.router(router);

app.start('#root');

这是

src/router.tsx

import React from 'react';
import { routerRedux, Switch, Route } from 'dva/router';
import Layout from './layouts';
import LoginPage from './components/LoginPage';
import Welcome from './components/welcome';
import SocialLoginSuccess from './components/socialLoginSuccess';
import { AwaitPromiseThenRender } from './components/AwaitPromiseThenRender';

const { ConnectedRouter } = routerRedux;
function RouterConfig({ history }: any) {
  //@ts-ignore
  return (
    <AwaitPromiseThenRender
      //@ts-ignore
      promise={typeof window.__$$notInOffice !== "undefined" ? Promise.resolve(true) : Office.onReady()}
    >
      <ConnectedRouter history={history}>
        <Layout>
          <Switch>
            <Route path="/sign">
              <LoginPage />
            </Route>
            <Route path="/home">
              <Welcome />
            </Route>
            <Route path="/app">
              <App />
            </Route>
            ... ...
            ... ...
        </Layout>
      </ConnectedRouter>
    </AwaitPromiseThenRender>
  );
}

export default RouterConfig;

这是

src/components/AwaitPromiseThenRender/index.tsx

import React, { Component } from 'react';

interface IProps {
  promise: Promise<any>;
  children: React.ReactNode;
}

interface IState {
  promiseHasResolved: boolean;
}

export class AwaitPromiseThenRender extends Component<IProps> {
  state: IState = { promiseHasResolved: false };
  constructor(props: IProps) {
    super(props);
    props.promise
      .then(() => this.setState({ promiseHasResolved: true }))
      .catch(e => console.log("invokeGlobalErrorHandler(e)"))
  }

  render() {
    const { children } = this.props;
    const { promiseHasResolved } = this.state;

    return promiseHasResolved ? children : null;
  }
}

有谁知道如何修改我们现有的代码以绝对避免

Office.js has not fully loaded
错误?

reactjs ms-office office-js dvajs
1个回答
0
投票

我建议遵循 yo office React 模板使用的模式。在 Office.onReady() 完成之前不要渲染。要查看完整的模板代码,请参阅安装 Yeoman 生成器 — Yo Office。运行“yo office”,然后选择 React 模板来生成项目。

let isOfficeInitialized = false;

const title = "Contoso Task Pane Add-in";

const render = (Component) => {
  ReactDOM.render(
    <AppContainer>
      <ThemeProvider>
        <Component title={title} isOfficeInitialized={isOfficeInitialized} />
      </ThemeProvider>
    </AppContainer>,
    document.getElementById("container")
  );
};

/* Render application after Office initializes */
Office.onReady(() => {
  isOfficeInitialized = true;
  render(App);
});
© www.soinside.com 2019 - 2024. All rights reserved.