【问题标题】:React-redux with Flow - action type name from imported constantReact-redux with Flow - 来自导入常量的动作类型名称
【发布时间】:2019-07-14 06:42:08
【问题描述】:

我在使用 Redux 的 React 应用程序中使用 Flow 进行类型检查,并且需要根据动作类型检查减速器中的动作形状,如下所述:https://flow.org/en/docs/react/redux/

reducer 代码:

import { ADD_USER, DELETE_USER } from './actionTypes'

type State = {
  users: { [userId: number]: { name: string, age: number } }
};  // exact State shape is not important for this case

type Action = 
  |{ type: ADD_USER, user: {name: string, age: number} }
  |{ type: DELETE_USER, userId: number };

function reducer(state: State, action: Action): State {
  switch(action.type) {
    case ADD_USER:
      return { ...state, users: { ...state.users, action.user } };

    case DELETE_USER:
      const { action.userId, ...newUsers } = state.users
      return { ...state, users: newUsers };

    default:
      return state;
  }

这不起作用,给出 Flow 错误Cannot get 'action.userId' because property 'userId' is missing in object type

当我在同一个文件中将动作类型定义为常量时,类型检查会起作用:

// import { ADD_USER, DELETE_USER } from './actionTypes'

const ADD_USER = 'ADD_USER';
const DELETE_USER = 'DELETE_USER';

type State = {
  users: { [userId: number]: { name: string, age: number } }
};  // exact State shape is not important for this case

type Action = 
  |{ type: ADD_USER, user: {name: string, age: number} }
  |{ type: DELETE_USER, userId: number };

function reducer(state: State, action: Action): State {
  switch(action.type) {
    case ADD_USER:
      return { ...state, users: { ...state.users, action.user } };

    case DELETE_USER:
      const { action.userId, ...newUsers } = state.users
      return { ...state, users: newUsers };

    default:
      return state;
  }

需要将动作类型名称作为字符串常量导入,因为它们也会在动作创建器中导入,以便将它们全部定义在一个文件 actionTypes.js(一种使用 react-redux 的标准方法)。

如何对导入的常量执行不相交联合的流类型检查?

【问题讨论】:

    标签: javascript react-redux flowtype


    【解决方案1】:

    我认为需要做一些事情。

    1) 将类型添加到actionTypes.js 中的操作类型。确保按如下方式分配操作类型:

    const ADD_USER: 'ADD_USER' = 'ADD_USER';
    const DELETE_USER: 'DELETE_USER' = 'DELETE_USER';
    

    2) 在reducer代码中Action类型的注解中,确保使用的是类型而不是动作类型的值,如下:

    import { ADD_USER, DELETE_USER } from './actionTypes'
    
    type Action = 
      |{ type: typeof ADD_USER, user: {name: string, age: number} }
      |{ type: typeof DELETE_USER, userId: number };
    

    3) 确保所有其他代码都是有效的 JavaScript,因为 users: { ...state.users, action.user }{ action.userId, ...newUsers } = state.users 看起来不像是进行解构和创建新对象的合法方式。

    【讨论】:

    • 谢谢@frontendgirl,那个符号:const ADD_USER: 'ADD_USER' = 'ADD_USER'; 成功了!
    猜你喜欢
    • 2020-09-23
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 2015-12-15
    相关资源
    最近更新 更多