我有一个reducer,用于存储应用程序中某个时刻从API端点收到的数据:
export type Payments = {|
+cycle_length: number,
+next_billing_date: string,
+paid_for_users: number,
+payment_method: number,
+is_trial: boolean,
+plan: number,
+price: string,
+status: string,
+subscription_id: string,
+team: number,
|};
const INITIAL_STATE: Payments = {
cycle_length: NaN,
next_billing_date: '',
paid_for_users: NaN,
payment_method: NaN,
plan: NaN,
is_trial: false,
price: '',
status: '',
subscription_id: '',
team: NaN,
};
因为我还使用Flow
类型检查器NaN值似乎是正确的初始值,因为它们不会引发null
或undefined
之类的错误。
到目前为止,我认为一切都很好。
但今天我偶然发现了。我在组件中实现了componentWillReceiveProps
:
componentWillReceiveProps({ creatingSubscriptionError, changingTeamPlanError, targetPlan, history, subscription }) {
if (creatingSubscriptionError || changingTeamPlanError) {
history.push('/payments/failure');
} else {
const hasChangedPlan = this.props.subscription.plan !== subscription.plan;
if (hasChangedPlan) {
history.push('/payments/success');
}
}
}
出于奇怪的原因,几乎立即安装的组件将我重定向到/payments/success
路由,即使reducer中的值没有改变。
那是因为那时:
this.props.subscription.plan !== subscription.plan
与
相同NaN !== NaN
总是会返回true
,即使从我的角度来看,也没有任何改变。
现在我认为嘿:只要react-redux
id在shouldComponentUpdate
进行浅比较 - 如果包含这些NaN道具 - 它总会返回true
,而实际上没有任何变化。< / p>
我不确定React
是否在对帐时或其他一些进程中比较道具,但这也是一个问题。我知道PureComponent
对道具的比较浅。
我想知道我是否在正确的轨道上,我是否应该在React
或Redux
中使用NaN作为默认值。
答案 0 :(得分:1)
这是非常不可取的,NaN遵循几个棘手的规则,如:
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
另外,在语义上它意味着&#34;不是数字&#34;,这很奇怪。
答案 1 :(得分:1)
我将数字的初始值设置为0
(因为0
不会以任何方式影响可能的计算,包括该值。您的代码也变得更具可读性,类型声明可以作为文档,而NaN
作为值非常混乱。
特殊情况是使用数字作为枚举(即在您的情况下,我认为您正在使用payment_method: number
进行此操作)。我会为给定集合的底值创建一个特殊的枚举(在这种情况下通常使用-1
)。