Reducer 在使用 redux-promise 和 axios 时返回 undefined

Posted

技术标签:

【中文标题】Reducer 在使用 redux-promise 和 axios 时返回 undefined【英文标题】:Reducer returns undefined when using redux-promise and axios 【发布时间】:2018-02-21 08:14:15 【问题描述】:

当我在 promise 解决后尝试调用回调时遇到了这个问题(使用 .then)事实证明,这给了我的 const request 某种与 reducer 不同的 promise返回未定义:

行动:

   export function lookup(company, callback) 
      const id = company.textfield;
      const url = `$ROOT_URL$id`;

      const request = axios.get(url)
       .then(() => callback())

      return 
        type: LOOK_UP,
        payload: request,
        meta: id
     ;
 

减速器:

import  LOOK_UP  from '../actions/index';

export default function(state = , action) 
    switch (action.type) 
        case LOOK_UP:
            const data = action.payload.data;
            const id = action.meta;

            if (data.Success === true) 
                return  ...state, [id]: data.CompanyInformation ;
             else 
                return state;
            
    
    return state;

如您所见,我将 axios 获取的 API 中的数据传递给我的 reducer。在此之后,我设置了状态,我需要调用“actions”中的回调(它会在组件内创建另一个动作调用)。不幸的是,我得到了一个错误,即 reducer const data = action.payload.data 是未定义的。

当我不使用此回调时,一切正常,但情况是我需要仅在此 reducer 返回新状态后调用该回调。

【问题讨论】:

有什么进展吗?你有时间尝试我的建议吗? 我现在看到了,这次调用了回调,但我认为这里的问题是它被触发得太早了。我的意思是,这个回调通过这个 LOOK_UP 操作传递从 reducer 返回的新状态。我必须创建另一个函数,该函数将在此状态更改后启动,而不仅仅是在 promise 解决时启动。 回调真的依赖于新的状态,还是仅仅依赖于request = axios.get(url)的返回?如果只是回调需要响应作为参数,那么您可以简单地使用我的第一个建议,但使用 callback(dataFromRequest);callback(dataFromRequest.data); 或您感兴趣的任何信息。您还可以包含 if 语句。等等,如果dataFromRequest.data.SUCESS !== true,则执行Promise.reject( ) 你使用什么库来实现承诺?你有标签redux-promise。是这个吗? github.com/acdlite/redux-promise 那里的例子太少了,很难看出它应该如何使用。是redux-promise 添加了.Success 吗? 是的,我正在使用 redux-promise,但是 .Success 来自 API(此 api 返回带有 data/null 和 Success true/false 的对象)。所以我认为最合理的做法是在这种情况下将回调与从请求返回的 dataFromRequest 一起使用。但我想对于我的减速器,我仍然需要返回类型为:LOOK_UP、有效负载:请求等的部分? 【参考方案1】:

使用另一个回调的最佳方式需要将中间件“redux-promise”替换为“redux-thunk”

import ReduxThunk from 'redux-thunk'
const store = createStore(applyMiddleware(ReduxThunk));

动作:

export function lookup(company, callback) 
  const id = company.textfield;
  const url = `$ROOT_URL$id`;


  return function(dispatch)  
        axios.get(url)
       .then((res) => 
            dispatch( type: LOOK_UP, payload: res,  meta: id );
            callback();
         )
      ;
 

减速器:

import  LOOK_UP  from '../actions/index';

export default function(state = , action) 
    switch (action.type) 
        case LOOK_UP:
            const data = action.payload.data;
            const id = action.meta;

            if (data.Success === true) 
                return  ...state, [id]: data.CompanyInformation ;
             else 
                return state;
            
    
    return state;

【讨论】:

【参考方案2】:

request 等于整个语句:

const request = axios.get(url)
   .then(() => callback())

所以如果callback() 没有返回任何东西,那么这个promise 将解决为空。我假设你正在通过这个调用获取一些数据,所以你需要传递这些数据,否则你的 reducer 永远不会得到它。像这样:

const request = axios.get(url)
   .then((dataFromRequest) =>  
     callback(); 
     return dataFromRequest; 
);

或者您可以将两者分开并编写如下内容:

const request = axios.get(url);
request.then(() => callback());

return 
    type: LOOK_UP,
    payload: request,
    meta: id
 ;

比较下面sn-p中的promise:

const promisedData = () => Promise.resolve(42);

promisedData()
  .then(data => console.log('Resolved data is ', data));


const promisedTrasformedData = () => 
   Promise.resolve(700)
   .then(data => data - 34);
   
   
promisedTrasformedData()
  .then(transformedData => console.log('Transformed data is ', transformedData));
  
  

const promisedAndLostData = () => 
  Promise.resolve(42)
 .then(data => returnNoting())

function returnNoting()  ;

promisedAndLostData()
 .then(lostData => console.log('Lost data: ', lostData))

【讨论】:

以上是关于Reducer 在使用 redux-promise 和 axios 时返回 undefined的主要内容,如果未能解决你的问题,请参考以下文章

Redux reducer 不更新 store/redux-promise 不解决

Redux-Promise 不会阻止被拒绝的 Promise

react常见面试题

常见的React面试题

使用 redux-promise 处理 redux 错误的正确方法

redux-promise:未捕获的 TypeError:中间件不是函数