React Redux 添加额外的操作字段导致承诺返回不同

Posted

技术标签:

【中文标题】React Redux 添加额外的操作字段导致承诺返回不同【英文标题】:React Redux adding extra field for action cause promise to return differently 【发布时间】:2017-09-26 03:31:27 【问题描述】:

我想在我的动作生成器中添加一个 isLoading 标志并在我的减速器中重置它。最初没有标志,我的代码可以工作,动作如下所示

export function getList() 
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return 
        type: FETCH_LIST, 
        payload: request,
    

reducer 看起来像

const INITIAL_STATE =  all: [], id: -1, isLoading: false ;

export default function (state = INITIAL_STATE, action) 
    switch (action.type) 
        case FETCH_COMIC_LIST: 
            console.log('reducer action =', action, 'state =', state)
            return 
                ...state, 
                all: action.payload.data.data.results,
                isLoading: false
            
        default:
            return state;
    

如您所见,对象返回正常,我可以通过 action.payload.data.data.results 获取我的列表

请注意,我使用 redux Promise 作为我的中间件来处理 Promise。

一旦我将操作更改为以下内容并重新运行代码,我的有效负载(如下图所示)将成为 Promise 而不是返回的对象

export function getComicList() 
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return 
        type: FETCH_COMIC_LIST, 
        isLoading: true, 
        payload: request,
    

为什么只是简单地添加另一个变量会导致这个问题?

【问题讨论】:

你能说出你使用的确切的承诺中间件吗? redux-promise github.com/acdlite/redux-promise 【参考方案1】:

Redux Promise 和 Redux Promise Middleware 都符合Flux Standard Action (FSA)。将meta 键添加到操作并在其中分配您的键/值对。

相关问题/答案:https://***.com/a/35362148/4290174

来自 FSA 文档:

可选的元属性可以是任何类型的值。它适用于不属于有效负载的任何额外信息。

【讨论】:

【参考方案2】:

试试这个 - 它是如何使用 redux-thunk 完成的 - 所以我希望它类似于 redux-promise-middleware。另请查看返回的内容:

all: action.payload 在你的减速器中

    export function getList() 
        const FIELD = '/comics'
        let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;

        // return a promise that the middleware should handle
        // return response or error from promise
        return axios.get(url)
          .then((response) => 
            type: FETCH_LIST,
            isLoading: true, 
            payload: response
          ).error((response) => 
            //handle error
          );
    

【讨论】:

这是不正确的。要解决这个问题,只需使用meta 字段,如正确答案中所述:***.com/a/48371940/2476275 如果 Redux 给你一个警告或者什么不要放在响应中,那就太好了,因为我永远不会知道。 你说得对,这将是解决这个问题的好方法,因为我注意到人们被它绊倒了。然而,meta 字段并不是 Redux 的要求,而是 Redux 中间件可以选择遵循的标准。或许该中间件需要考虑一些事情。【参考方案3】:

我认为最干净和最react-redux的方式是:

//types:
const FETCH_LIST_START = "…";
const FETCH_LIST_SUCCESS = "…";
const FETCH_LIST_ERROR = "…";

//action
const loadList = url => dispatch => 
  dispatch(type: FETCH_LIST_START );

  fetch(url)
    .then(res => 
      if (res.status !== 200) throw new Error('load failed');
      dispatch( 
        type: FETCH_LIST_SUCCESS,
        payload :  res  
      )

    )
    .catch(err => dispatch( 
      type: FETCH_LIST_ERROR, 
      payload:  error  )
    );
;

//REDUCER
case: FETCH_LIST_START:
  return Object.assign(, state,  isLoading: true );
  break;
case: FETCH_LIST_SUCCESS:
  return Object.assign(, state,  
     isLoading: false, 
     data: action.payload.res
  );
  break;
case FETCH_LIST_ERROR:
  …
  break;

假设您使用的是 redux-thunk。基本思想是让你的reducer处理状态,包括设置isLoading的东西,这样,你可以在请求状态改变时更新你的组件……上面的代码不是复制/粘贴准备好的,它是为了传输想法。

【讨论】:

几个问题...1。这是使用 redux-thunk 中间件吗? 2.你知道为什么我原来的代码在添加isLoading的时候会乱码吗? 在问题的上下文中(使用 Redux Promise 中间件),这是不正确的。要解决这个问题,只需使用meta 字段,如正确答案中所述:***.com/a/48371940/2476275

以上是关于React Redux 添加额外的操作字段导致承诺返回不同的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 thunk 和 useDispatch(react-redux 挂钩)从操作中返回承诺?

当操作中有一个数字时,Redux-promise 没有解决一个承诺

组件中不必要的额外重新渲染导致删除字段的值

React-Redux 设计方法 - 可编辑文本字段双向绑定的 Redux 操作或本地函数

从 React Redux Thunk 返回承诺

在 Redux 中的 bindActionCreators 之后无法得到承诺