2016-08-07 5 views
0

私はデータが初期化される私のアプリのスプラッシュ画面に取り組んでいます。ナビゲーション実験:小道具を場面に渡すには?

欲求の結果は、単純である:componentWillMountに

  1. ロードデータ:ビューがロードされたデータにloading indicator
  2. を示す:図は、第1の後check icon
  3. を示している:他のシーンに移動

ビューをloading indicatorからに変更するには、私はdataReadyスプラッシュ画面のシーンに渡される小道具を更新する必要がありますが、ナビゲーション状態を更新しないとこれを行う方法がわかりません。ナビゲーション状態のrouteオブジェクトを介して小道具をシーンに渡す)。ここで

は私の試み(期待どおりに動作しない)である。その結果

class MainRouter extends React.Component { 

    componentWillMount() { 
    // Load data. 
    this.props.initApp(); 
    } 
    componentWillReceiveProps(nextProps) { 
    // initAppReady is set to true 1 second after data loaded. 
    if (nextProps.initAppReady) { 
     this.props.handleNavigation({ type: 'PUSH', route: { key: 'home' } }); 
    } 
    } 

    renderScene = props => { 
    switch (props.scene.key) { 
     case 'scene_splash_screen': 
     // dataReady is set to true after data loaded. 
     return (<SplashScreen dataReady={this.props.dataReady} />); 

     case 'scene_home': 
     return (<Home />); 

     default: 
     return null; 
    } 
    } 

    render() { 
    return (
     <NavigationCardStack 
     direction={'vertical'} 
     navigationState={this.props.mainRoutes} 
     renderScene={this.renderScene} 
     /> 
    ); 
    } 
} 

props.dataReadySplashScreenシーンがそれに応じて更新されませんので、変更されたとき、renderSceneメソッドが呼び出されません。

+0

申し訳ありませんが、私が誤ってあなたのポストを編集する代わりに試してみました私の答え...私の編集を無視してください。 (それはちょうど拒否されました、それについては残念です) –

答えて

1

新しいAppLoaderコンポーネントを作成すると、スプラッシュ画面が表示され、初期データが読み込まれます。また、ルータに小道具としてinitAppReadyを渡す代わりに、initApp関数が約束を返すようにする必要があります。これは、アプリの準備ができたら解決し、AppLoaderは1秒の一時停止を行い、ホームシーンにナビゲートできます。

注:ホームルートをスタックにプッシュすることに気付きました。スタックをホームルートに置き換えることをお勧めします。それを押すと、誤ってスプラッシュ画面に戻ることがありますが、これはおそらくあなたが望むものではありません。ここで

は、私が何を意味するかの例です:

MainRouter.js

class MainRouter extends React.Component { 

    renderScene = props => { 
    switch (props.scene.key) { 
     case 'scene_splash_screen': 
     return (<AppLoader initApp={this.props.initApp} handleNavigation={this.props.handleNavigation} />); 

     case 'scene_home': 
     return (<Home />); 

     default: 
     return null; 
    } 
    } 

    render() { 
    return (
     <NavigationCardStack 
     direction={'vertical'} 
     navigationState={this.props.mainRoutes} 
     renderScene={this.renderScene} 
     /> 
    ); 
    } 
} 

AppLoader.js

const AFTER_INIT_DELAY = 1000; 
class AppLoader extends React.Component { 

    static propTypes = { 
    initApp: PropTypes.func, 
    handleNavigation: PropTypes.func, 
    }; 

    constructor(props) { 
    super(props); 
    this.state = { 
     dataReady: false, 
    }; 
    } 

    componentWillMount() { 
    this.props.initApp() 
     .then(() => { 
     this.setState({dataReady: true}, this.afterAppInit); 
     }) 
     .catch(() => { 
     // Do something if the app init fails 
     }) 
    } 

    afterAppInit =() => { 
    setTimeout(() => { 
     this.props.handleNavigation({ type: 'REPLACE', route: { key: 'home' } }); 
    }, AFTER_INIT_DELAY); 
    } 

    render() { 
    return (
     <SplashSceen dataReady={this.state.dataReady} /> 
    ); 
    } 
} 
+0

'AppLoaderコンポーネント'によって、あなたはredux世界の 'container'を意味しますか?そうであれば、表示する複数のビューステートがコンテナ内にラップされてからrenderSceneに渡される必要があるすべてのシーンでこれは意味しますか? – czphilip

+0

いいえ、 'AppLoader'コンポーネントは、最初のアプリケーションのロードのオーケストレーションを処理する単なるコンポーネントです。単にスプラッシュ画面を表示し、データの読み込み(ストアなどの更新が可能)を開始し、ホーム画面に「リダイレクト」します。 これは単に論理をよりよくカプセル化し、ルータで厄介になり、レンダリングされたシーンを更新しようとするのを防ぎます。 –

+0

副作用として、私が示唆するようにこれを独自のコンポーネントに抽出することで、App Updatingなどのものを簡単に中央の場所に追加することができます。 –

関連する問題