2017-11-08 4 views
1

私は、ここで私のためにやや難しい状況があります。asynchronosアクションが完了したときにのみ、次のページに移動しますか? React-native

ユーザーがログオンすると、ユーザーデータでRedux状態を更新する必要があります。私はWebトークンを取得するlogin methondを呼び出します。その後、私はredux-thunkで2つの非同期アクションをディスパッチしたいと思います。問題は次のとおりです。

これらのアクションがディスパッチされ、APIからの応答があるときは、すでに別の画面に移動していて、リストをレンダリングするためのデータはRedux状態ではありません。

質問:私の状態が更新され、次のページに移動するまで、プログラムを「保持」する方法はありますか?

これは、ときにユーザーがログイン中に何が起こるかです:その後、私はしたい

export const profileLoad =() => {  

     return (dispatch) => { 
      AsyncStorage.getItem('token_id') 
      .then((token_id) => fetch("http://10.0.2.2:8000/api/profile/", { 
       method: "GET", 
       headers: { 
       'Authorization': 'JWT ' + token_id 
       } 
      }) 
      .then((response) => response.json()) 
      .then((answer) => { 
       dispatch({ type: PROFILE_LOAD, payload: answer}); 
      }) 
      .done()); 
     } 
    } 

export const productsLoad =() => { 

    return (dispatch) => { 
     AsyncStorage.getItem('token_id') 
     .then((token_id) => { 

      fetch("http://10.0.2.2:8000/api/profile/products/", { 
       method: "GET", 
       headers: { 
       'Authorization': 'JWT ' + token_id 
       } 
      }).then((anser) => anser.json()) 
      .then((response)=> { 
       dispatch ({ type: PRODUCTS_LOAD, payload: response}) 
      }) 
     } 
     ).done(); 
    } 

} 

:ログインこれら二つのアクションがcompletly派遣さsouldと状態が更新されるべき時にどこか

fetch("http://10.0.2.2:8000/api/api-token-auth/", { 
     method: "post", 
     headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json' 
     }, 
     body: JSON.stringify({ 
      email: this.props.email, 
      password: this.props.password, 
     }) 
     }).then((response) => response.json() 
     ).then((jResponse) => { 
      console.log(jResponse); 
      this._onValueChange('token_id', jResponse.token); 
      this.props.loginUserSuccess(); 
      this.props.navigation.navigate('MainMenue'); 
     }).catch((error) => { 
      console.log(error); 
      this.props.loginUserFail(); 
      }) 
    } 

別の画面をナビゲートし、ListViewでリストをレンダリングして、製品とプロファイルからJSONデータを表示します。

- >私はそれを最終的に理解しました。 ソリューション 2を述べたように戻り、アクションクリエイターから約束) 1)あなたは、メソッドにコールバック関数を入れていることを確認してください

export const loadAllProfileData = ({navigate}) => { 
    return (dispatch) => { 
     dispatch(profileLoad()) 
     .then(() => dispatch(productsLoad())) 
     .then(() => navigate('MainMenue')) 
    }; 
} 

export const profileLoad =() => {  

      return (dispatch) => { 
       return AsyncStorage.getItem('token_id') 
       .then((token_id) => fetch("http://10.0.2.2:8000/api/profile/", { 
        method: "GET", 
        headers: { 
        'Authorization': 'JWT ' + token_id 
        } 
       }) 
       ).then((response) => response.json()) 
       .then((answer) => { 
        dispatch({ type: PROFILE_LOAD, payload: answer}); 
       }) 

      } 
     } 


export const productsLoad =() => { 

    return (dispatch) => { 
     return AsyncStorage.getItem('token_id') 
     .then((token_id) => 
      fetch("http://10.0.2.2:8000/api/profile/products/", { 
       method: "GET", 
       headers: { 
       'Authorization': 'JWT ' + token_id 
       } 
      }) 
     ).then((answer) => answer.json()) 
     .then((response)=> { 
       dispatch ({ type: PRODUCTS_LOAD, payload: response}) 
      }) 

    } 
} 

答えて

1
あなたの行動クリエイターからの約束を返すことができ

thenchainそれら。アクションクリエーターにreturn AsyncStorage.getItem() ...を追加するだけでそれを行うことができます。次に、あなたはできる:

fetch(url) //login 
    .then(dispatch(profileLoad)) 
    .then(dispatch(productsLoad)) 
    .then(this.props.navigation.navigate('MainMenue')) 
    .catch(err => //handle error) 

promises chainingについてもっと読む。

編集:簡単な例のようになります。

import { createStore, applyMiddleware } from 'redux' 
import thunkMiddleware from 'redux-thunk' 
import fetch from 'node-fetch'; 

const ROOT_URL = 'https://jsonplaceholder.typicode.com'; 

const FETCH_DATA = 'FETCH_DATA'; 

const url = `${ROOT_URL}/users`; 

function fetchData() { 
    return (dispatch) => { 
     return fetch(url) 
      .then(res => res.json()) 
      .then(data => { 
       dispatch({ 
        type: FETCH_DATA, 
        payload: data[0].name 
       }); 
      }) 
    } 
} 

function reducer(state = [], action) { 
    if (action.type === FETCH_DATA) { 
     console.log('Action.payload:', action.payload); 
    } 

    switch (action.type) { 
     case 'FETCH_DATA': 
      return [...state, action.payload]; 

     default: 
      return state; 
    }; 
} 

let store = createStore(
    reducer, 
    applyMiddleware(thunkMiddleware) 
) 

store.subscribe(() => 
    console.log('Store State: ', store.getState()) 
) 

fetch(url) 
    .then(res => res.json()) 
    .then(data => data) 
    .then(store.dispatch(fetchData())) 
    .then(store.dispatch(fetchData())) 
+0

だから、今行動クリエイターが戻ってきている: '(AsyncStorage.getItemを返す)'あなたが返すように派遣していないためにすべての呼び出しを削除するには、意味ですかコールバック関数?アクションクリエーターで何らかのアクションが派遣されなければならないので、私には混乱しているようです... –

+0

あなたはディスパッチをそのまま残します。プロミスを返す理由は、前に 'resolve'にフェッチを待つことができるということですあなたは次のものに行きます。 –

+0

これらのばかげた質問には申し訳ありません。しかし、ディスパッチ機能は、サンク・ミドルウェアによって提供されます。私は単にコンポーネントレベルでそれを呼び出すことができますか?ログインは還元的アクションでなければならないのでしょうか?そこでは、コンポーネントレベルの状態を使用しました。今、私は単に 'ディスパッチ'が定義されていないことを得ています。 –

関連する問題