Почему React Flow отвергает этот подход? - PullRequest
0 голосов
/ 29 сентября 2019

Я создаю приложение React с Context API и React Hooks.Я пытаюсь следовать лучшим практикам.Для этого я использую Flow и пытаюсь придерживаться его предупреждений.

У меня есть ситуация, когда после входа в систему пользователь хочет сохранить некоторые данные об этом пользователе в SessionContextЯ построил.Учитывая, что на данный момент существует только 3 фрагмента данных, и все они примитивны, я подумал, что имеет смысл иметь только одно Действие Редуктора:

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 типа действий следующим образом, а затем определяю тип отправки из этого:

export type SessionAction = 
  | UserEmailAction
  | UserAccessLevelAction
  | CurrentCompanyNameAction;

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

Есть 4 предупреждениясообщения поверх sessionReducer в этом коде:

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

Сообщения сродни следующему: «Невозможно позвонить useReducer с sessionReducer, связанным с reducer, так как число [1] несовместимо сстрока [2] в свойстве currentCompanyName возвращаемого значения. "

Неправильно ли я определил типы действий или Flow не достаточно умен, чтобы различать 3 шаблона?Кстати, этот подход, кажется, работает нормально при запуске.

1 Ответ

0 голосов
/ 30 сентября 2019

Поток не достаточно умен.Но вы можете использовать другой подход, который поток поймет:

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

Это также сократит общий объем кода, поэтому я не думаю, что это слишком плохо.

...