【问题标题】:Ionic react app showing blank page after first state change离子反应应用程序在第一次状态更改后显示空白页面
【发布时间】:2020-09-05 13:40:56
【问题描述】:

我的 ionic react 应用程序出现以下问题。

  • 初始启动后,登录页面按预期显示。
  • 成功登录后,this.state.login.status 变为 true 并加载 Home 组件(查看该组件的日志输出)。但屏幕只显示一个空白页。
  • 重新加载页面后(包含成功的登录数据;我将其保存在localStorage),Home 组件按预期显示。

这种行为在每台设备(Chrome、Android、Ios)上都是相同的。并且控制台不显示任何错误消息。
我只看到了 Android 和 Chrome 之间的一个区别。如果我使用 chrome 注销,则会出现 Login 页面,我可以重新登录(没有空白页面)。所以问题只针对第一次状态变化。
如果我使用的是我的 Android 应用程序(使用 Capacitor 构建),每次状态更改时都会出现空白页面,我必须在每次登录/注销后重新启动应用程序。

有谁知道什么可能导致这种行为?我已经搜索过类似的问题,但没有一个有效。例如将 package.json 中的 homepage 更改为 '.'

App.tsx

import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { IonApp, IonRouterOutlet } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import Home from './pages/Home';
import Login from './pages/Login';
import Xxx from './util/Xxx';

/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';

/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';

/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';

/* Theme variables */
import './theme/variables.css';

interface AppProps {};
interface AppState {
  isSignedIn: boolean,
  user: string
};

class App extends React.Component<AppProps, AppState> {
  constructor(props: AppProps) {
    super(props);

    const login = Xxx.isSignedIn();
    this.state = {
      isSignedIn: login.status,
      user: login.user
    };
    this.checkLogin = this.checkLogin.bind(this);
  }

  checkLogin() {
    const login = Xxx.isSignedIn();
    this.setState({
      isSignedIn: login.status,
      user: login.user
    });
  }

  render() {
    return (
      <IonApp>
        <IonReactRouter>
          <IonRouterOutlet>
            <Route
              path="/home"
              exact={true}
              render={
                props => {
                  return this.state.isSignedIn ?
                    <Home {...props} user={this.state.user} checkLogin={this.checkLogin}/> :
                    <Login checkLogin={this.checkLogin}/>;
                }
              }
            />
            <Route exact path="/" render={() => <Redirect to="/home" />} />
          </IonRouterOutlet>
        </IonReactRouter>
      </IonApp>
    );
  }
};

export default App;

【问题讨论】:

    标签: reactjs typescript ionic-framework react-router local-storage


    【解决方案1】:

    看看使用 React.Context 创建一个用于管理应用程序状态的上下文,那么你不需要通过属性到处传递状态

    const App: React.FC = () => {
      const { authCtx } = React.useContext(AppContext);
    
      return (
        <IonApp>
          {authCtx.authenticated ? (
            <IonReactRouter>
              <IonSplitPane contentId="main">
                <Menu />
                <IonRouterOutlet id="main">
                  <Route path="/page/:name" component={Page} exact />
                  <Redirect from="/" to="/page/Inbox" exact />
                </IonRouterOutlet>
              </IonSplitPane>
              }
            </IonReactRouter>
          ) : (
            <IonReactRouter>
              <Route path="/auth/login" component={LoginPage} exact />
              <Route
                path="/auth/create-account"
                component={CreateAccountPage}
                exact
              />
              <Redirect from="/" to="/auth/login" exact />
            </IonReactRouter>
          )}
        </IonApp>
      );
    };
    

    IN 索引.ts

    import { AuthProvider } from "./helpers/my-context";
    
    ReactDOM.render(
      <AuthProvider>
        <App />
      </AuthProvider>,
      document.getElementById("root")
    );
    

    在 my-context.ts 中

    import React from "react";
    
    // create the context
    export const Context = React.createContext<any>(undefined);
    
    // create the context provider, we are using use state to ensure that
    // we get reactive values from the context...
    
    export const AuthProvider: React.FC = ({ children }) => {
      // the reactive values
      const [authCtx, setAuthCtx] = React.useState({
        authenticated: null,
        user: null,
      });
    
      // the store object
      let state = {
        authCtx,
        setAuthCtx,
      };
    
      // wrap the application in the provider with the initialized context
      return <Context.Provider value={state}>{children}</Context.Provider>;
    };
    
    export default Context;
    

    【讨论】:

      【解决方案2】:

      你能试试这个吗?

      我认为是因为虚拟 dom 没有改变...

          if (!this.state.isSignedIn) {
             return <Login checkLogin={this.checkLogin}/>
          }
      
          return (
            <IonApp>
              <IonReactRouter>
                <IonRouterOutlet>
                  <Route
                    path="/home"
                    exact={true}
                    render={
                      props => <Home {...props} user={this.state.user} checkLogin={this.checkLogin}/>
                      }
                    }
                  />
                  <Route exact path="/" render={() => <Redirect to="/home" />} />
                </IonRouterOutlet>
              </IonReactRouter>
            </IonApp>
          );
      

      【讨论】:

      • 似乎可以使用 chrome :) 我现在将使用 android 应用程序进行测试。无论如何,为什么 ionic this 在他们的wiki 上引用此方法?
      • 说真的我不知道...看到这个我觉得有点傻...但是像我这样的白痴,如果它有效,它就有效...
      • 安卓也可以,非常感谢!!为此奋斗了好几个小时。
      • 你是否也将IonApp标签包含在Login组件中?
      • @AaronSaunders,您能否提供一个更好(且有效)的答案来解决问题?
      猜你喜欢
      • 2022-09-29
      • 2020-12-25
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      相关资源
      最近更新 更多