在Redux Reducer中执行Ajax提取?

问题描述:

我试图围绕访问Redux actionCreators中的状态;而是做了以下操作(在reducer中执行ajax操作)。为什么我需要为此访问状态 - 因为我想用存储在状态中的CSRF令牌执行ajax。在Redux Reducer中执行Ajax提取?

有人可以告诉我,如果以下被认为是不好的做法/反模式?

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; 
    } 
} 

从终极版文档:

改变状态的唯一方法是发出一个动作,对象描述发生了什么。 不要将API调用放入reducer中。减速器只是一个纯函数,它会采用先前的状态和一个动作,并返回下一个状态。记住要返回新的状态对象,而不是改变以前的状态。

操作应描述更改。因此,该操作应该包含新版本状态的数据,或者至少指定需要进行的转换。因此,API调用应该进入调度动作以更新状态的异步操作。减肥药必须是纯净的,并且没有副作用。

查看async actions了解更多信息。

从了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的澄清,你们俩都说了很多道理。我用thunk实现了异步操作;但是,我无法弄清楚的是,如何进行api调用(提取),但在提取时将状态数据添加到我的POST变量中?例如:CSRF令牌? – sammysaglam

+1

@sammysaglam查看更新的答案。你可以有第二个参数,它是一个函数'getState',它将返回基本状态对象。 – Matthew

+0

工作!惊人!非常感谢!我正试图弄清楚现在好一个小时! – sammysaglam

作为每终极版的准则。

减速机保持纯净非常重要。在减速机内你永远不应该做的事情:

  • 改变它的参数;
  • 执行API调用和路由转换等副作用;
  • 调用非纯函数,例如Date.now()或Math.random()。

如果你问是否反模式,那么是绝对的。

但是,如果你问什么是解决方案。

  1. 在这里,你需要从你的行动创造者派遣异步动作
  2. 使用“终极版,形实转换”或“终极版 - 传奇”为
  3. 可以访问状态,并创建一些异步操作

例如,您的行动的创建者中(只是举例)

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的澄清,你们俩都说了很多道理。我用thunk实现了异步操作;但是,我无法弄清楚的是,如何进行api调用(提取),但在提取时将状态数据添加到我的POST变量中?例如:CSRF令牌? – sammysaglam

+1

@sammysaglam你可以访问行动创建者的状态。 – WitVault