2

次のスニペットを実行すると、ルーターがスローされます

import React from 'react';
import {Scene, Router} from 'react-native-router-flux';

export default App extends React.Component {
  componentDidMount() {
      // This fails
      Actions.login();
  }

  render() {
    return (
      <Router>
        <Scene key="root" hideNavBar>
          <Scene key="login" component={Login} />
          <Scene key="main" component={Main} initial />
        </Scene>
      </Router>
    );
  }
}

ルーターは App.componentDidMount によってマウントされているはずなので、すべてのアクションが機能しているはずです。
タイムアウトを 2 秒に設定すると、機能します。誰かがそれに遭遇しましたか?ここで何か間違ったことをしていますか?

4

1 に答える 1

2

それで、ようやく問題が何であるかを理解しました。
問題は、シーンの初期化に時間がかかることではありません。
Action.login には、ルート componentDidMount の後にある最初の実際のレンダリングの後に Router が挿入する Actions.callback が必要です。

ここで何が起こるか:
ルート レンダー関数が呼び出され
た ルーター レンダー関数が state.reducer なしで呼び出されたので、何もしません。
ルーター componentDidMount が呼び出されました - ここでアクションが初期化され、リデューサーが状態に保存されます (setState は非同期です)。
ルート componentDidMount - ここでは、コールバックがまだ初期化されていません。
Router render called - この呼び出しは setState before によってトリガーされます。これで Actions.callback が注入されました。

したがって、2 回目のレンダリングの後、ルーターが初期化されます。

任意の setTimeout よりも優れた解決策を見つけることができました。
Router の render メソッドをオーバーライドし、データでレンダリングされた直後に、親に通知します。

class OverrideRouter extends Router {
    constructor(props) {
        super(props);
        this.render = this.overrideRender;
    }
    overrideRender() {
        const result = super.render();
        if (!result) {
            return result;
        }
        // after first initialization use the regular render.
        this.render = super.render;
        if (this.props.onRouterInitialize) {
            // need this setTimeout to allow this method to complete so that the Actions.callback is populated
            setTimeout(this.props.onRouterInitialize, 10);
        }
        return result;
    }
}

編集
問題を完全に修正し、プルリクエストを送信して解決しました。 https://github.com/aksonov/react-native-router-flux/pull/1137

于 2016-09-01T22:45:11.130 に答える