redux - 流程:在 reducer 中的操作之间进行选择
问题描述
TLDR:我在 Try Flow (链接) 中模拟了我的问题。你能帮我解决吗?
问题的完整描述:
在 Redux reducer 中,我在三个操作之间进行选择。一个动作可以有任何类型,但它的显着特点是它的有效载荷中有一个特定的字段(payload.entities.items
在这个例子中)。另外两个动作有特定的类型来区分它们,并且也有不同的有效负载:
const FOO = 'FOO'
const BAR = 'BAR'
type ActionWithEntities = {|
type: string,
payload: {|
entities: {|
items: {
[string]: string
}
|}
|}
|}
type ActionWithFoo = {|
type: typeof FOO,
payload: {|
foo: string
|}
|}
type ActionWithBar = {|
type: typeof BAR,
payload: {|
bar: string
|}
|}
type Action =
| ActionWithEntities
| ActionWithFoo
| ActionWithBar
根据操作,我想在减速器中做任何适当的事情(并不重要):
function reducer(state: State, action: Action) {
if (action.payload && action.payload.entities && action.payload.entities.items) {
return Object.assign({}, state, action.payload.entities.items);
}
switch(action.type) {
case FOO:
const foo = action.payload.foo;
return { foo }
case BAR: {
const bar = action.payload.bar;
return { bar }
}
default:
return state;
}
}
我的问题是,Flow 没有看到 if 语句处理第一个操作(因为其他操作的有效负载中没有该entities
字段),并在 switch 语句中抱怨我尝试使用的字段(foo
或bar
在此示例中)第一个动作中不存在。
让Flow开心的正确方法是什么?
解决方案
流不喜欢这样的原因是因为 ActionWithEntities 的 type 字段是 string 类型,这意味着它的值可能是 FOO 或 BAR。现在,您的逻辑将阻止它触发开关/案例,但流程无法遵循该逻辑并改进类型。解决它的一种方法是显式键入 ActionWithEntities 的类型字段
所以像
type ActionWithEntities = {|
type: 'OTHER' | 'OTHER2' | 'OTHER3',
payload: {|
entities: {|
items: {
[string]: string
}
|}
|}
|}
推荐阅读
- java - ResourceConfig 实例不包含 REST API 中的任何根资源类异常
- ios - TableView Reload rows Limitation
- python - “ImportError:无法导入名称”使用 flask_sqlalchemy
- stripe-payments - Stripe Billing 的付款信息
- c++11 - 如何阻止 C++ 自动将 double 转换为 int?
- javascript - 动态添加文本输入字段
- c# - C#在文本框中的光标位置插入字符
- css - 在 Less 中应用 CSS :not() 和 :hover
- ios - 2 可滚动视图中的 UIcollectionview
- r - 在 R 中的向量中从 0 开始索引