为什么React Flow拒绝这种方法?

问题描述 投票:0回答:1

我正在使用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种动作类型组合如下,然后从中定义一个Dispatch类型:

export type SessionAction = 
  | UserEmailAction
  | UserAccessLevelAction
  | CurrentCompanyNameAction;

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

此代码中sessionReducer上方有4条警告消息:

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

消息类似于此:“由于数字[1]与返回值的属性useReducer中的字符串[2]不兼容,因此无法将sessionReducer绑定到reducer来调用currentCompanyName。”

我是否定义了错误的动作类型,或者Flow是否不够智能,无法区分这三种模式?顺便说一下,这种方法在运行时似乎可以正常工作。

react-hooks flowtype react-context
1个回答
0
投票

流量不够智能。但是您可以使用流程可以理解的其他方法:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.