2016-10-10 91 views
1

我在我的狀態中有2個對象,我通過在請求中傳遞id來調用通用API來獲取數據。如何使用通用API來調度redux中的多個動作創建器?

以下是我fetch打電話,而觸發receiveSectionA我的狀態更新部1.第一部分。

export function fetchSection(sectionCode){ 
    return(dispatch,getState,api)=>{ 
    const endPoint = 'url/?sectionCode='+sectionCode 
    const method = 'GET' 
    const isAuth = true 
    const promise = api(endPoint,method,isAuth) 
    promise 
    .then(response => 
     response.json().then(json => ({ 
     status:response.status , 
     json 
     }) 
    )) 
    .then(
     ({ status, json }) => { 
     if(status >= 200 && status < 300) { 
      const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json)) 
      dispatch(receiveSectionA(sectionDictionary)) 
     } 
     if (status >= 400) { 
      //throw error 
     } 
     }, 
     err => { 
     console.log("error"+err); 
     } 
    ); 
    } 
} 

現在我做出同樣的呼籲sectionB其中火災以下內容: -

dispatch(receiveSectionB(sectionDictionary)) 

現在,因爲上述fetch通話一樣有什麼辦法可以讓這個通用。我覺得有太多的代碼重複。

我在想切換的情況下派遣基於sectionCode不同的行動,但我有大約20節,我認爲的代碼就會變得很複雜。

有沒有更好的辦法呢?

回答

1

據我所知,您正在尋找一個dynamic function call。您可以使用eval這可能會導致意外的結果。所以,謹慎使用。

期待你有兩個功能receiveSectionAreceiveSectionB;

export function fetchSection(sectionCode){ 
    return(dispatch,getState,api)=>{ 
    .................... 
    )) 
    .then(
     ({ status, json }) => { 
     if(status >= 200 && status < 300) { 

      const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json)) 
      let funToCall = 'receiveSection' + sectionCode + '(sectionDictionary)'; // preparing function to call 
      dispatch(eval(funToCall)); // Calling Function 
     } 
     if (status >= 400) { 
      //throw error 
     } 
     }, 
     err => { 
     console.log("error"+err); 
     } 
    ); 
    } 
} 

編輯: 瞭解更多關於eval尤其是Security本條 https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

+0

這看起來很有趣。但你意想不到的結果是什麼? –

+0

答案更新了鏈接..閱讀,學習,忘記...:D –

0

在這琢磨了一下後,顯然eval是不是一個好的選擇。

我想我會嘗試Javascript支持哪些功能作爲參數傳遞的驚人的東西之一。

在發送操作時,我將receiveActionCreator作爲回調函數傳遞。

所以我fetch現在是: -

export function fetchSection(callback,sectionCode){ 
    return(dispatch,getState,api)=>{ 
    .................... 
    )) 
    .then(
     ({ status, json }) => { 
     if(status >= 200 && status < 300) { 

      const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json)) 

      dispatch(callback(sectionDictionary)); // Calling Function 
     } 
     if (status >= 400) { 
      //throw error 
     } 
     }, 
     err => { 
     console.log("error"+err); 
     } 
    ); 
    } 
} 

現在我可以通過從不同的點多個接收器,當我通過避免重複的代碼從分派不同部分的動作。

0

我看不到很多來自reducer的代碼,但在我看來,您的行爲有太多的邏輯。通常動作只是爲了修改應用程序狀態,所以請仔細考慮應用程序狀態的形狀,並在減速器可以計算狀態的操作中提供最少的信息。此外,如果您必須轉換json並檢查每個請求的狀態代碼,爲什麼不在api模塊中執行它,如果您無法做任何有關錯誤的事情,那麼您不應該處理它們,在api中處理或在應用程序狀態中反映它們。應用業務邏輯總是存在於縮減器中。在此之後,您的操作看起來會更好,您不必擔心代碼重複。希望這可以幫助你。

0

因此搜索這個後,我終於找到了我在redux-docs讀的東西。

我用重複使用reducer邏輯來處理重複動作,狀態。這基本上包裹了我的reducer函數的父函數,我將id作爲參數傳遞給它,然後動態地從我的id創建動作類型。

以下代碼應該真的解釋清楚。它來自文檔本身。

function createCounterWithNamedType(counterName = '') { 
    return function counter(state = 0, action) { 
     switch (action.type) { 
      case `INCREMENT_${counterName}`: 
       return state + 1; 
      case `DECREMENT_${counterName}`: 
       return state - 1; 
      default: 
       return state; 
     } 
    } 
} 
相關問題