【问题标题】:Redux Actions must be plain objects. Use custom middleware for async actionRedux Actions 必须是普通对象。使用自定义中间件进行异步操作
【发布时间】:2017-05-01 13:37:41
【问题描述】:

我收到错误消息“Redux 操作必须是普通对象。使用自定义中间件进行异步操作。”使用下面的代码。

export const getFriends = () => async(): Action => {

  const requestConfig = {
    httpMethod: 'GET',
    version: 'v2.7',
  };
  let hasMore = false;
  let friends = [];

  do {
    const infoRequest = new GraphRequest(
    '/me/friends',
    requestConfig,
    (error, result) => {
      if (error) {
        alert('Error fetching data facebook friends');
      } else {
        result.data.forEach((value) => {
            friends.push(value)
        });
        if (result.paging && result.paging.next) {
          hasMore = true;
          requestConfig.parameters.after = result.paging.cursors.after;
        } else {
          hasMore = false;
        }
      }
    });
    await new GraphRequestManager().addRequest(infoRequest).start();
  } while (hasMore);
  return {
    type: 'GET_FRIENDS',
    payload: friends    // this is empty because there is no await on GraphAPI
  };
};

如果我删除异步并等待,返回的朋友是空的,因为函数调用在 GraphAPI 调用返回之前返回

export const getFriends = () => (): Action => {

  const requestConfig = {
    httpMethod: 'GET',
    version: 'v2.7',
  };
  let hasMore = false;
  let friends = [];

  do {
    const infoRequest = new GraphRequest(
    '/me/friends',
    requestConfig,
    (error, result) => {
      if (error) {
        alert('Error fetching data facebook friends');
      } else {
        result.data.forEach((value) => {
            friends.push(value)
        });
        if (result.paging && result.paging.next) {
          hasMore = true;
          requestConfig.parameters.after = result.paging.cursors.after;
        } else {
          hasMore = false;
        }
      }
    });
    new GraphRequestManager().addRequest(infoRequest).start();
  } while (hasMore);
  return {
    type: 'GET_FRIENDS',
    payload: friends    // this is empty because there is no await on GraphAPI
  };
};

【问题讨论】:

    标签: asynchronous react-native redux react-redux redux-thunk


    【解决方案1】:

    这个错误的意思就是它听起来的样子。 Redux 期待一个普通的对象。我看到用 redux-thunk 标记的问题。如果您使用的是 redux-thunk,则可能您没有使用中间件正确设置商店。如果您不使用 redux-thunk,那么我会推荐它作为调度异步操作的首选库。

    这将为您提供有关调度非普通对象的 redux 操作的深刻见解。 How to dispatch a Redux action with a timeout?

    编辑:您错过了实际的调度,并试图简单地返回普通对象......需要返回一个调度......类似于以下内容(尚未测试,但应该让你接近):

        export const getFriends = () => {
          return (dispatch) => {
            const requestConfig = {
              httpMethod: 'GET',
              version: 'v2.7',
            };
            let hasMore = false;
            let friends = [];
    
            do {
              const infoRequest = new GraphRequest(
                '/me/friends',
                requestConfig,
                (error, result) => {
                  if (error) {
                    alert('Error fetching data facebook friends');
                  } else {
                    result.data.forEach((value) => {
                        friends.push(value)
                    });
                    if (result.paging && result.paging.next) {
                      hasMore = true;
                      requestConfig.parameters.after = result.paging.cursors.after;
                    } else {
                      hasMore = false;
                      return dispatch({
                        type: 'GET_FRIENDS',
                        payload: friends               
                      });
                    }
                  }
              });
              await new GraphRequestManager().addRequest(infoRequest).start();
            } while (hasMore);
          }
        };
    

    【讨论】:

    • 是的,我正在使用 redux-thunk。看我做的时候。我需要等待因为做一段时间。 GraphAPI 不会一次性返回全部回报,所以我必须分页。我该怎么做?
    • 为了跟进该代码 sn-p,redux-thunk 非常棒,因为您可以从同一个操作中调度多个事件。因此,您可以调度一个事件来表示加载过程的开始,然后在每次接收到数据时调度 ADD_FRIENDS 方法,而不是等到结束。不需要返回任何东西,您只需要在必要时实际 dispatch() 普通对象操作
    • 但是while循环退出了。
    • 假设您还有更多工作要做。有更多=真;否则,您甚至根本不会尝试使用 while 循环来更改 hasMore。
    • 问题出在异步 GraphRequestManager 上。在第一个 do while 迭代中,您正在等待启动 GraphRequestManager。 await 不等待 GraphRequest 数据回调,只是开始请求。所以回调可能没有时间触发甚至尝试修改/更新 hasMore。您可以在回调和 while 循环(定义 infoRequest 之外)中添加一些 console.logs 来确认或拒绝这一点。
    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 2020-11-05
    • 2019-12-26
    • 2017-11-16
    • 1970-01-01
    相关资源
    最近更新 更多