【问题标题】:Why does React Flow reject this approach?为什么 React Flow 拒绝这种方法?
【发布时间】:2019-09-29 06:25:43
【问题描述】:

我正在使用 Context APIReact Hooks 构建一个 React 应用程序。我正在尝试遵循最佳实践。为此,我使用Flow 并尝试遵守其警告。

我有一种情况,一旦用户登录,我想在我建立的SessionContext 中存储有关该用户的一些数据。鉴于现在只有 3 条数据并且它们都是原始的,我认为只有一个 Reducer Action 是有意义的:

export const sessionReducer = (state: SessionState, action: SessionAction) => {
  switch (action.type) {
    case UPDATE_SESSION_PROP: {
      return {
        ...state,
        [action.propName]: action.payload
      };
    }

    default: {
      return state;
    }
  }
}

以下是我为说明这 3 种数据类型而创建的操作类型:

export type UserEmailAction = {type: 'UPDATE_SESSION_PROP',
                               propName: 'currentUserEmail',
                               payload: string};

export type UserAccessLevelAction = {type: 'UPDATE_SESSION_PROP',
                                     propName: 'currentUserAccessLevel',
                                     payload: number};

export type CurrentCompanyNameAction = {type: 'UPDATE_SESSION_PROP',
                                        propName: 'currentCompanyName',
                                        payload: string};

在我的SessionContext中,我将这3种Action类型组合如下,然后从中定义一个Dispatch类型:

export type SessionAction = 
  | UserEmailAction
  | UserAccessLevelAction
  | CurrentCompanyNameAction;

type Dispatch = (action: SessionAction) => void;

在此代码中,sessionReducer 之上有 4 条警告消息:

const [state: SessionState, dispatch: Dispatch] = useReducer(sessionReducer, defaultState);

消息类似于:“不能调用 useReducersessionReducer 绑定到 reducer 因为数字 [1] 与返回值的属性 currentCompanyName 中的字符串 [2] 不兼容。”

我是否错误地定义了 Action 类型,或者 Flow 只是不够智能来区分这 3 种模式?顺便说一句,这种方法在运行时似乎运行良好。

【问题讨论】:

    标签: react-hooks flowtype react-context


    【解决方案1】:

    Flow 不够智能。但是您可以使用流会理解的不同方法:

    type SessionState = {
      currentUserEmail: string,
      currentUserAccessLevel: number,
      currentCompanyName: string,
    };
    
    type SessionAction = {
      type: 'UPDATE_SESSION_PROP',
      payload: $Shape<SessionState>,
    };
    
    const sessionReducer = (state: SessionState, action: SessionAction) => {
      switch (action.type) {
        case UPDATE_SESSION_PROP: {
          return {
            ...state,
            ...action.payload
          };
        }
    
        default: {
          return state;
        }
      }
    }
    

    https://flow.org/try/#0JYWwDg9gTgLgBAbzgVwM4FMBK6AmyDG6UcAvnAGZQQhwDkU6AhvjLQNwBQH+EAdqvACqABQAiAQQAqAUQD6AZWnz5ASQDyAOVnDMa4XAC8dERJkKlqzdt3D2XGAE8w6OPPSpUwPvJiMYLowQOODh8ZCgGXhhBDChpEEZgABsALjgBKGBeAHMAGmDQ8Mjo2PF8Qg8AGXQAN3RUuF5kEAAjInyQsIj0KIBhajBGXgcNRhB0NIysvI4STg50AA9IWDhHZ1d3Tz4ymC9eQ0QC9YnjMSk5RWV1LR09Wg64QYckiEYcNIASeQALRmcADxuDz7Hx+dAAPnyc3sThcomAqEGMHwP0OAApmHs+GlgdteLt9gBKQwQuA1CDAHDzHDofBJRgMcmMuC08iMZBJGBg-y4rag3z+eY8fjwDAgvjYPCEYhGdECcF8iW8HnoXJwLH7JX4wl8EkGMlBEKoADuwBRaMxLH2ADoTiSjSFQowMHATBdzNcrHdhGlHU64AwYOEDv6A3AbZGFf5HuGI5HNXwbc9Xu8CgGYRmuAG2RyuX7006gyH0oL0JwsyESLMuCKBHAANrR054gXg9U4RHI1FpBFIvyogC6hzQWFwBCI8v5kvHMo76HZnO5ZaJbCAA

    它也会减少代码的总量,所以我认为它不会太糟糕。

    【讨论】:

    • 谢谢。你介绍了$shape。我已经开始寻找这个并且找不到参考。可以分享一个吗?
    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2021-05-01
    • 2021-07-19
    相关资源
    最近更新 更多