Closed nighca closed 2 years ago
Fix #61
FieldState
DebouncedState
DebouncedFieldState
Simplify interface IState: initialValue, validationDisabled, resetWith, dirtyWith are removed, for
IState
initialValue
validationDisabled
resetWith
dirtyWith
Change behavior of dirty
dirty
为什么调整 dirty 的定位(从基于值的比较改为记录状态)。
本来我们这样判断 dirty:如果当前值(value)与初始值(initialValue)“相同”,则认为 dirty: false,否则为 true。这里的关键是,如何判定“相同”;其逻辑是这样的:
value
dirty: false
true
FormState
ArrayFormState
因此对于 FieldState、FormState / ArrayFormState,都会有:
state.dirty // false state.onChange(state.initialValue) state.dirty // false
但是对于 DeouncedState 与 TransformedState(即这个 PR 中的 ProxyState),(几乎)无法去正确地实现一个满足上述要求的 dirtyWith:
DeouncedState
TransformedState
ProxyState
以某个 DeouncedState 实例 s 为例,s.value 比 s.$.value 更新,通过 s.$.dirtyWith(s.initialValue) 得到的是 s.$.value 与 s.initialValue 是否“相同”,而无法得出 s.value 与 s.initialValue 是否相同;注意,因为 s 不关心 s.$ 具体是什么 state class,只知道它是实现了 IState 接口的实例,因此 s 也不具备应该怎么比较 s.value 与 s.initialValue 的知识。
s
s.value
s.$.value
s.$.dirtyWith(s.initialValue)
s.initialValue
s.$
再以某个 TransformedState 实例 s 为例,调用 s.$.dirtyWith 前它需要先对 initialValue 进行转换,而对同一个值的两次转换可能得到两个引用不相等的转换结果;因此如果 s.$ 是个 FieldState,即便当前 s.value 与 s.initialValue 是引用相等的,因为其转换后结果不一定引用相等,因此 s.$.dirtyWith 的结果可能不准确。
s.$.dirtyWith
综上,基于值的比较来判定 dirty 的做法在新的背景下不可持续(它要求 state 与其使用者更高程度的耦合)。这里将 dirty 的定位调整为:
If value has been touched.
即,值是否被设置过,无论设置后的值与初始值是否一致
不过这个 PR 中对具体实现的调整并不彻底,这里只调整了 FormState (& ArrayFormState) 的 dirty 实现,FieldState 的实现暂时没有调整(还是直接判断 value 与 initialValue 是否引用相等)。
在 #74 中我们会将 FieldState 的 dirty 行为调整为与上述定位一致
Fix #61
FieldState
DebouncedState
&DebouncedFieldState
for debouncing purposeSimplify interface
IState
:initialValue
,validationDisabled
,resetWith
,dirtyWith
are removed, forChange behavior of
dirty
备注
为什么调整
dirty
的定位(从基于值的比较改为记录状态)。本来我们这样判断
dirty
:如果当前值(value
)与初始值(initialValue
)“相同”,则认为dirty: false
,否则为true
。这里的关键是,如何判定“相同”;其逻辑是这样的:FieldState
,引用相等则为“相同”FormState
/ArrayFormState
,将value
与initialValue
按 child state 的形状拆开,逐个去按 child state 的逻辑进行判断是否相同(通过调用子 state 的dirtyWith
方法);若全都相同,则认为“相同”因此对于
FieldState
、FormState
/ArrayFormState
,都会有:但是对于
DeouncedState
与TransformedState
(即这个 PR 中的ProxyState
),(几乎)无法去正确地实现一个满足上述要求的dirtyWith
:以某个
DeouncedState
实例s
为例,s.value
比s.$.value
更新,通过s.$.dirtyWith(s.initialValue)
得到的是s.$.value
与s.initialValue
是否“相同”,而无法得出s.value
与s.initialValue
是否相同;注意,因为s
不关心s.$
具体是什么 state class,只知道它是实现了IState
接口的实例,因此s
也不具备应该怎么比较s.value
与s.initialValue
的知识。再以某个
TransformedState
实例s
为例,调用s.$.dirtyWith
前它需要先对initialValue
进行转换,而对同一个值的两次转换可能得到两个引用不相等的转换结果;因此如果s.$
是个FieldState
,即便当前s.value
与s.initialValue
是引用相等的,因为其转换后结果不一定引用相等,因此s.$.dirtyWith
的结果可能不准确。综上,基于值的比较来判定
dirty
的做法在新的背景下不可持续(它要求 state 与其使用者更高程度的耦合)。这里将dirty
的定位调整为:即,值是否被设置过,无论设置后的值与初始值是否一致
不过这个 PR 中对具体实现的调整并不彻底,这里只调整了
FormState
(&ArrayFormState
) 的dirty
实现,FieldState
的实现暂时没有调整(还是直接判断value
与initialValue
是否引用相等)。在 #74 中我们会将
FieldState
的dirty
行为调整为与上述定位一致