2017-08-04 6 views
0

私はReduxのactionCreators内の状態にアクセスすることを念頭に置いています。代わりに次のことを行いました(減速機でajax操作を実行しました)。状態にアクセスする必要があるのはなぜですか?なぜなら、状態に格納されているCSRFトークンを使用してajaxを実行したいからです。Redux ReducerでAjaxフェッチを実行しますか?

誰かが次のことが悪い習慣/反パターンとみなされているかどうか教えてください。 Reduxのドキュメントから

export const reducer = (state = {} , action = {}) => { 

    case DELETE_COMMENT: { 

     // back-end ops 
     const formData = new FormData(); 
     formData.append('csrf' , state.csrfToken); 
     fetch('/delete-comment/' + action.commentId , { 
      credentials:'include' , 
      headers:new Headers({ 
       'X-Requested-With':'XMLHttpRequest' 
      }) , 
      method:'POST' , 
      body:formData 
     }) 

     // return new state 
     return { 
      ...state , 
      comments:state.comments.filter(comment => comment.id !== action.commentId) 
     }; 
    } 

    default: { 
     return state; 
    } 
} 

答えて

2

状態を変更する唯一の方法は、アクション、何が起こったのか記述するオブジェクトを放出することです。 API呼び出しをレデューサーに入れないでください。レジューサーは、前の状態と動作を取り、次の状態を返す純粋な関数です。以前の状態を変更する代わりに、新しい状態オブジェクトを返すことを忘れないでください。

アクションで変更を説明する必要があります。したがって、アクションには、新しいバージョンの状態のデータが含まれているか、少なくとも作成する必要がある変換を指定する必要があります。そのため、API呼び出しは、状態を更新するアクションをディスパッチする非同期アクションに移行する必要があります。 Reducersは常に純粋でなければならず、副作用がありません。

詳細については、async actionsをご覧ください。

Reduxの例から非同期動作の例:Reduxののガイドラインに従ってとして

function fetchPosts(subreddit) { 
    return (dispatch, getState) => { 
     // contains the current state object 
     const state = getState(); 

     // get token 
     const token = state.some.token; 

     dispatch(requestPosts(subreddit)); 

     // Perform the API request 
     return fetch(`https://www.reddit.com/r/${subreddit}.json`) 
      .then(response => response.json()) 

      // Then dispatch the resulting json/data to the reducer 
      .then(json => dispatch(receivePosts(subreddit, json))) 
    } 
} 
+0

はあなたが両方言ったことは多くの意味を行い、あなたの&@ WitVaultの明確化のためにありがとうございました。私はサンクで非同期アクションを達成しました。しかし、私が理解できないことは、どうやってapi呼び出し(フェッチ)を行うのですか?フェッチ時に、状態からPOSTバーにデータを追加しますか?例えば:CSRFトークン? – sammysaglam

+1

@sammysaglamは更新された答えをチェックします。 2番目のパラメータは、基本状態オブジェクトを返す 'getState'関数です。 – Matthew

+0

はうまくいった!素晴らしい!どうもありがとうございます!私は今これで良い一時間のためにこれを理解しようとしていました! – sammysaglam

4

還元剤が純粋なままであることは非常に重要です。減速機の内部で決して行うべきでないこと:

  • 引数を変更します。
  • APIコールやルーティング移行などの副作用を実行します。
  • 非純粋な関数を呼び出します。 Date.now()またはMath.random()。

アンチパターンであるかどうかを尋ねる場合は、それは絶対です。

しかし、解決策は何かを尋ねる場合。ここで

  1. は、あなたのアクションクリエイターから非同期アクションをディスパッチする必要が
  2. 使用することを
  3. のための「Reduxの-サンク」または「Reduxの-武勇伝」あなたは状態にアクセスし、いくつかの非同期アクションを作成することができます
  4. あなたのアクション・クリエーターの内側(ジャスト例えば)

例えば

export function deleteCommment(commentId) { 
    return dispatch => { 
     return Api.deleteComment(commentId) 
      .then(res => { 
       dispatch(updateCommentList(res)); 
      }); 
    }; 
} 

export function updateCommentList(commentList) { 
    return { 
     type : UPDATE_COMMENT_LIST, 
     commentList 
    }; 
} 

編集:あなたは状態にアクセスすることができます -

export function deleteCommment(commentId) { 
    return (dispatch, getState) => { 
     const state = getState(); 
     // use some data from state 
     return Api.deleteComment(commentId) 
      .then(res => { 
       dispatch(updateCommentList(res)); 
      }); 
    }; 
} 
+0

&@ Matthewの解説に感謝します。両方のことが意味を成しています。私はサンクで非同期アクションを達成しました。しかし、私が理解できないことは、どうやってapi呼び出し(フェッチ)を行うのですか?フェッチ時に、状態からPOSTバーにデータを追加しますか?例えば:CSRFトークン? – sammysaglam

+1

@sammysaglamあなたはaction-creatorの状態にアクセスできます。 – WitVault