2016-06-22 54 views
3

由於redux thunk調用動作創建者異步返回的函數,我如何確保在調用動作創建者之後,redux實際上在繼續之前調度了該動作?如何等待重新加載thunk以調度行動

我需要在每次向服務器發送POST請求前獲取CSRF令牌,並且這兩個過程都有相應的操作。

問題是,如果我連續調用這些動作創建者,POST動作是出於某種原因在CSRF動作發出之前派發的。我想把這些擔憂分開,所以我不想把這些行動結合起來。

我該如何將動作創建者調用代碼與redux thunk同步調度這些動作?

回答

3

您可以讓thunk動作創建者作爲Promise,更容易控制異步作業。

export function createXHRAction(xhrType, dispatch, options) { 
    // you can customize createXHRAction here with options parameter. 

    dispatch({ type: xhrType, data: { fetching: true, data: [] }); 

    return new Promise((resolve, reject) => { 
     fetch(options.url, { ... }) 
     .then((response) => { 
      // to getting server response, you must use .json() method and this is promise object 
      let parseJSONPromise = response.json(); 

      if(response.status >= 200 && response.status < 300) { 
       parseJSONPromise.then((result) => { 
        dispatch({ type: xhrType, data: { fetching: false, data: result.data }); 
        resolve(result.data); 
       }); 
       return parseJSONPromise; // make possible to use then where calling this 
      } 
      else { 
       return parseJSONPromise.then(res => { 
        reject({ message: res.error.message }); 
       }); 
      } 
     }) 
     .catch((error) => { 
      // handles common XHR error here 
     }); 
    }); 
} 
現在

您可以輕鬆地創建新的XHR操作是這樣的:

import { createXHRAction } from './actions'; 

export function getUser(id) { 
    return (dispatch) => { 
     return createXHRAction('user', dispatch, { 
      method: 'get', 
      url: `/user/${id}` 
     }); 
    }; 
} 

現在你可以使用thunk的動作就像是同步的:

import { dispatch } from './store'; 
import { getUser } from './action/user'; 

class SomeComponent extends React.Component { 
    ... 
    loadData(id) { 

     // from here, store's state should be { fetching: true, data: [] } 
     dispatch(getUser(id)) 
     .then((userData) => { 
      // now from here, you can get the value from parameter or you can get it from store or component props if super component passing it by redux provider. 
      // store state should be { fetching: false: data [..., ...] } 
      // do something with received data 
     }) 
     .catch((error) => { 
     })); 

    } 
} 
2

你需要等待CSRF令牌請求在開始POST請求之前完成。

我認爲這將是更好的包裝所有的代碼轉化爲行動的創建者

function postAction(data) { 
    fetchToken().then((token) => { 
     //you have got token here and can use it for the POST-request. 
     doPost(data, token).then(() => { 
      //dispatch success action if you need so 
     }) 
    }) 
} 
+0

雖然這是一個建設性的解決方法,存在這樣的情況將是非常有幫助的序列派遣行動作爲海報問。例如。您正在一個複雜的項目中使用現有動作創建器中的可信遺留代碼,該動作創建器「正常工作」,並且最好在不修改或重構的情況下調用這些代碼。 –