【问题标题】:Nested action makes reducer state different from redux store?嵌套动作使reducer状态与redux store不同?
【发布时间】:2019-11-23 04:03:49
【问题描述】:

我有一个问题,我的 redux 存储与我在减速器中的状态不同。这个问题与我如何称呼我的行为有关。我的目标是获得更新的状态,以便我可以在减速器中针对不同的情况调用它(例如state.numbers)。我在按下按钮时调用一个动作。这个动作的属性会被发送到不同的reducer,然后调用一个函数(这个函数调度导致问题的动作)。

这是按下按钮时调用的动作:

export const startReminder = (item) => {
  return (dispatch) => {
    dispatch({ //this dispatch works great and isn't the issue
      type: START_REMINDER,
      id: item.id
    });
    scheduleNotification.startReminder(item); //the issue is this function right here
  };
};

这个函数我将简化为这个,因为它重现了问题:

export const scheduleNotification = {
  async startReminder() {
    store.dispatch(testing(1));
  }
};

被分派的测试动作如下所示:

export const testing = (number) => {
  return {
    type: 'testing',
    number
  };
};

然后在我的减速器中,我按下一个不同的按钮,触发一个记录state.numbers 的案例。如果我在添加了一个数字(或多个)的同一会话中触发此案例,它们将不会被记录。但是如果我重新加载会话然后让状态记录它(我保存数据),它会正确地将它记录到控制台。我尝试将这个分派的动作从开始提醒中移出,并解决了这个问题。所以它与在辅助函数中被调用在另一个动作中被调用有关。

我希望我可以移动它,但这并不是那么简单。在 scheduleNotification 函数中,我获得了需要存储在商店中的唯一 ID。在我拥有该 ID 之前,我无法发送操作。如果有人知道出了什么问题或有任何建议,我将不胜感激,我不知道是什么导致了这个问题。

举个例子,假设我的 numbers 数组是空的,然后我向它添加一个数字。即使我在 redux 存储中看到它,如果在添加它的同一会话期间记录它,它也会作为一个空数组出现。假设我添加了一个数字,然后重新加载应用程序,然后记录状态。这次它会正确显示其中的数字。

【问题讨论】:

  • startReminder异步的方式是什么?您需要await 来电获取身份证吗?此外,store.dispatch 似乎关闭,不应该发生在动作创建者中。但也许你添加这个只是为了调试?
  • startReminder 是异步的,因为在我没有包含的代码中(不会导致问题)我必须等待返回通知 ID。然后我想调用store.dispatch() 并使用该ID 并将其添加到我的reducer 中。为什么store.dispatch 关闭?那一定是问题所在
  • store.dispatch 似乎关闭了,因为您可以直接使用dispatch。我假设startReminder 是一个重击动作。您想在等待 scheduleNotification 执行异步操作之前还是之后调度 START_REMINDER
  • 之前肯定。开始提醒动作会影响屏幕。 scheduleNotification 是一个后端的东西,所以应用程序会跟踪他们的所有通知。
  • 好吧,我希望我理解你的上下文正确,我会发布一个答案。

标签: javascript reactjs react-native redux


【解决方案1】:
export const startReminder = (item) => {
  return async (dispatch) => {
    dispatch({
      type: START_REMINDER,
      id: item.id
    });

    // This is where the request to your backend happens.
    // startReminder needs to return a promise or be async itself
    const number = await scheduleNotification.startReminder(item);

    // Since a request can fail, you would normally have error handling here,
    // like a try {} catch {} block, but I left that out for the sake of simplicity.

    dispatch({
        type: 'testing',
        number,
    });
  };
};

【讨论】:

  • 是的,这解决了!非常感谢,我已经坚持了一个多星期。你是男人。你有没有机会解释一下为什么直接从商店发货会干扰一切?
  • 不客气。不确定为什么您的 store.dispatch 不起作用,可能取决于您的实际代码。但总的来说,thunk 是按照我发布的方式编写的。
猜你喜欢
  • 2020-10-21
  • 2018-11-29
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
相关资源
最近更新 更多