为Redux操作定义类型的正确方法是什么?

时间:2016-10-12 15:36:35

标签: redux flowtype

我有一个使用Redux进行状态管理的应用程序,我尝试添加Flow类型注释。

我在这里创建了一个非常简单的测试用例,概述了我遇到的问题。

我已经创建了一个联合Action类型,然后在reducer函数中,我使用switch根据动作决定要返回的状态&#39 ; s type财产。在switch语句的每种情况下,我都在访问action参数的不同属性。

我不明白为什么Flow告诉我它无法在action参数上找到某些属性。一切似乎都得到了恰当的定义,我真的无法在这里看到任何错误。

这是我的测试用例:

https://flowtype.org/try/#0C4TwDgpgBAggxsAlgewHZQLxQFBSgHygG8pRIAuKAcgDEBJAJQGUAVKgGigBMBDYHygHkARgCsICKAF9cBYqXARKVJgFEAwoIByAEQ5REwCAFs6XSgGdgAJ0SoA5tOzYy0JvyOZisgDaIrlDDW1jwgADwi4ggAfOzYMtgAZgCuqAgo6NYQXMlwEAAUVnxKUO7FnDzpaIFVqACUlKjJxsIQ1t54FgDuhnAAFlD5lUhoAHSudR14UHA8FtC0jKxUlESy01BZwMnW6EVGo35Wo4l2XHSoXBAAHvmGJpjRBkbGo4hcmBhYwxmjvPxvLh1ADc6ycG1m82oak0uhWUw2Wx2ew8EEO-mAJzOFyut3uxkezxMgM+31qbxeZhBYJkGyuiR4yR8wHIYLwSN2UAADKC8DIpEA

我认为可能这个问题与使用switch语句有关,所以这里使用的是if版本,问题相同:

https://flowtype.org/try/#0C4TwDgpgBAggxsAlgewHZQLxQFBSgHygG8pRIAuKAcgDEBJAJQGUAVKgGigBMBDYHygHkARgCsICKAF9cBYqXARKVJgFEAwoIByAEQ5REwCAFs6XSgGdgAJ0SoA5tOzYy0JvyOZisgDaIrlDDW1jwgADwi4ggAfOzYMtgAZgCuqAgo6NYQXMlwEAAUVnxKUO7FnDzpaIFVqACUlKjJxsIQ1t54iIlQ+ZVIaAB0rpgYWLSMrFR1HXhQWcDJ1uhFRgN+VgOJdlx0qFwQAB75hiaY0QZGxgOIXCNYfRkDvPzXXHUA3LIyeLJdPQ+DYajMZqTS6KYzPDzRbLDwQNb+YCbba7fZHE7GM4XEyvO5QAGoa6XMwfL6yWTQpZQAAMnykQA

1 个答案:

答案 0 :(得分:0)

首先,请注意您的reduce功能不是有效的减速器。 redux reducer必须具有以下签名

(state: State, action: Action) => State

Flow对优化很悲观(理论上你可以改变回调中的action.data引用)。帮助Flow保持细化的一种方法是使用const绑定(docs

function reduce(state: State, action: Action): number {
  switch (action.type) {
    case 'FIRST': 
      const data = action.data;
      return state.list.findIndex(item => item.id === data.id);
    case 'SECOND': 
      const itemId = action.itemId
      return state.list.findIndex(item => item.id === itemId);
    default:
      return 0;
  }
}

或者,IMO甚至更好,将案例分成几个辅助函数

function findIndex(state: State, id): number {
  return state.list.findIndex(item => item.id === id);
}

function reduce(state: State, action: Action): number {
  switch (action.type) {
    case 'FIRST': 
      return findIndex(state, action.data.id)
    case 'SECOND': 
      return findIndex(state, action.itemId)
    default:
      return 0;
  }
}

此外,您可以在redux仓库中找到流式应用程序的示例(请参阅examples / todos-flow)