2017-08-19 10 views
2

私のアプリケーションにどのようにしたいかを動作させるのに問題があります。私はReactとReduxにはかなり新しいので、私に同行してください。AxiosとReduxでエラー状態を追加する

今すぐ私はthis.props.fetchData('usernamehere')と呼んでユーザーに関するデータを取得できます。成功するとReactコンポーネントの更新に使用するthis.props.profileが更新されます。この問題は、エラーを処理することです。

私はFETCH_DATA_ERROR減速を追加することによって、これを処理しようとしましたが、私がいる問題は、それは404のそれはまだちょうどthis.props.errorを更新するのではなく、空のオブジェクトでthis.props.profileを置き換えたとき。理想的には、新しいプロファイルが見つかるまで現在のプロファイルを保存し、更新して入力したユーザー名でエラーが何であるかをユーザーに表示したいと考えています。this.props.error誰もが、彼らは非常に高く評価されるだろう任意の提案を持っている場合

import { FETCH_DATA, FETCH_DATA_ERROR } from '../actions/types'; 

const INITIAL_STATE = { profile: null, error: null } 

export default function(state = INITIAL_STATE, action) { 
    switch(action.type) { 
    case FETCH_DATA: 
     return { ...state, profile: action.payload.data }; 

    case FETCH_DATA_ERROR: 
     return { ...state, error: action.payload }; 

    default: 
    return state; 
    } 
} 

import axios from 'axios'; 
import { FETCH_DATA, FETCH_DATA_ERROR } from './types'; 

export const ROOT_URL = 'https://api.github.com/users' 

export function fetchData(user) { 
    const request = axios.get(`${ROOT_URL}/${user}`) 
    .catch(function (error) { 
    return { 
     type: FETCH_DATA_ERROR, 
     payload: error 
    } 
    }); 

    return { 
    type: FETCH_DATA, 
    payload: request 
    } 
} 

と減速:

は今の私は、次のアクションの作成者を設定しています。私は正しい道にいるように感じるが、どこが間違っているのか分からないようだ。

+0

なぜ'{type:FETCH_DATA}'を 'then'に置かないでください。 –

+0

@SamRadそれについても考えて、私は 'アクションは普通のオブジェクトでなければなりません。非同期アクションにはカスタムミドルウェアを使用してください。 ' –

+0

それは本当です。 'redux-thunk'や他の儀式の罠を使わない限り、非同期の行動を取ることはできません。簡単な方法は、あなたのAPIコールを別々に書いて、あなたのアクションの作成者を 'then'と' catch'に呼ぶことです。それは理にかなっていますか? –

答えて

1

これまでのところ、リクエストの開始を示すアクション(FETCH_DATA)とリクエストが失敗したことを示すアクション(FETCH_DATA_ERROR)があります。典型的には、これは、要求が肯定応答(おそらくFETCH_DATA_SUCCESS)をもたらしたことを示す、3番目のものをモデルにしています。

あなたはそれを最初に派遣のみFETCH_DATAようhttps://github.com/gaearon/redux-thunkようなものを使用して、アクションの作成者を書き換える必要があるでしょうし、その後axios.getのその後/キャッチ・ハンドラでは、あなたは成功または失敗のアクションをディスパッチ:

import { FETCH_DATA, FETCH_DATA_SUCCESS, FETCH_DATA_ERROR } from '../actions/types'; 

// ASYNC ACTION CREATOR 

export const fetchData = user => (dispatch) => { 
    dispatch({ 
     type: FETCH_DATA 
    }); 

    return axios.get(`${ROOT_URL}/${user}`) 
     .then(response => dispatch({ 
      type: FETCH_DATA_SUCCESS, 
      payload: response 
     })) 
     .catch(error => dispatch({ 
      type: FETCH_DATA_ERROR, 
      payload: error 
     })); 
}; 


// REDUCER 

const INITIAL_STATE = { 
    profile: null, 
    error: null 
}; 

export default function(state = INITIAL_STATE, action) { 
    switch(action.type) { 
     // Start of request - discard old data and reset old errors. 
     case FETCH_DATA: 
      return { 
      // It's important to set all of these to properly model the request lifecycle 
      // and avoid race conditions etc. 
      profile: null, 
      error: null 
     }; 

     // End of request - save profile and signal that there was no error. 
     case FETCH_DATA_SUCCESS: 
      return { 
       profile: action.payload.data, 
       error: null 
      }; 

     // End of request - discard old profile and save error, to display it to the user for example. 
     case FETCH_DATA_ERROR: 
      return { 
       profile: null, 
       error: action.payload 
      }; 

     default: 
      return state; 
    } 
} 
+0

これはうまくいきますが、エラーが発生した場合に 'this.props.profile'に既に存在するプロファイルをヌルに戻すことは望ましくなく、単に既存のプロファイルを保持して画面上にエラーを点滅させたいだけです。このような状況でプロファイルをプロファイルとして保持するにはどうすればよいですか? –

+0

nmはそれを解決しました! '... state'を忘れてしまった。ありがとうございました! –

+0

とにかく状態に2つのプロパティしかないので、私はあなたの '... state'を削除しました。もちろん、必要に応じて減速機を調整することができます。私の主なポイントは、2つではなく3つのアクションを持つことでした.Btwでは、isFetchingDataのようなフラグを状態に追加して、ローディングインジケータのようなものをユーザに表示することさえできます。 – timotgl