为什么 React Flow 拒绝这种方法?
Why does React Flow reject this approach?
我正在使用 Context API
和 React 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);
消息类似于:"Cannot call useReducer
with sessionReducer
bound to reducer
because number [1] is incompatible with string [2] in property currentCompanyName
of the return value."
我是否错误地定义了 Action 类型,或者 Flow 是否不够智能来区分 3 种模式?顺便说一句,这种方法似乎在 运行.
时工作正常
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;
}
}
}
它也会减少整体代码量,所以我认为这不是太糟糕。
我正在使用 Context API
和 React 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);
消息类似于:"Cannot call useReducer
with sessionReducer
bound to reducer
because number [1] is incompatible with string [2] in property currentCompanyName
of the return value."
我是否错误地定义了 Action 类型,或者 Flow 是否不够智能来区分 3 种模式?顺便说一句,这种方法似乎在 运行.
时工作正常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;
}
}
}
它也会减少整体代码量,所以我认为这不是太糟糕。