qiniu / formstate-x

Manage state of form with ease.
https://qiniu.github.io/formstate-x
MIT License
33 stars 10 forks source link

v3.0.0 #84

Closed nighca closed 2 years ago

nighca commented 2 years ago

Changes of v3

See #47 for details.

Migrating from v2

Breaking Changes

1. Naming Adjustment

2. Changes of FieldState

In v3, we now no longer debounce value change of FieldState. Correspondingly, it is not supported to specify delay (of debouncing) when constructing FieldState instances now (for details: #61).

If you need the debouncing of value change, you can use DebouncedFieldState instead. It's almost the same as FieldState in v2:

const state = new DebouncedFieldState(1) // with default delay: 200ms
const state = new DebouncedFieldState(1, 500) // with delay: 500ms

As a result, field _value of FieldState instances is removed and UI binding is simplified: bindInput is no longer provided in v3, just use state.value & state.onChange to bind states to UI inputs:

<input
  value={state.value}
  onChange={e => state.onChange(e.target.value)}
/>

Note that if state is an instance of DebouncedFieldState, you should use state.$ instead of state to do binding (for details: Debounced State).

3. FormState[mode=array] -> ArrayFormState

In v2, there are two modes for FormState: object / array, corresponding for two cases:

In v3, the mode object remains the same. Mode array is not supported any more, and we provided class ArrayFormState for the array cases:

const state = new ArrayFromState([foo, bar], createChildState)

Its APIs differs slightly, for details: Input List & #54

4. Others

Other important (while not breaking) changes

1. TransformedState

For situations where UI value differs with business value, we provide TransformedState. It works perfect within composition, for details: Transformed State & #56

2. set & onChange

In v2, only FieldState instances provided methods set & onChange to change their value. If you want to change the value of a FormState instance, you need to access its child states (state.$.*) first. In v3, you can call set or onChange directly on any state, as long as it implemented interface IState. The semantics for these methods remains the same.

Compare

// v3
const state = new FormState({ foo: fooState, bar: barState })
state.set({ foo: 1, bar: 2 })

with

// v2
const state = new FormState({ foo: fooState, bar: barState })
state.$.foo.set(1)
state.$.bar.set(2)

The way in v3 (state.set({ foo: 1, bar: 2 })) is much simpler, and it introduces lower coupling between parent states and child states.

3. ownError & hasOwnError

In v2, only instances of FormState provided fields ownError & hasOwnError. In v3, you can access ownError & hasOwnError on any states which implemented interface IState. And they are recommended (instead of error & hasError) for UI binding purpose. for details: #71

4. The brand-new docs

We built brand-new documents site for v3. It will be helpful to read them first, especially for key concepts in formstate-x.


v3 变更

详见 #47

升级文档

不兼容变更

1. 命名调整

2. FieldState 变更及输入控件的绑定

v3 中 FieldState 不再对 value 变更添加 debounce,对应地也不再支持在构造 FieldState 时指定 debounce 的 delay(详见 #61)

如果业务上确实需要对 value 变更 debounce 后再去响应,可以使用 DebouncedFieldState 代替;DebouncedFieldState 的构造方式与 v2 中的 FieldState 一致:

const state = new DebouncedFieldState(1) // with default delay: 200ms
const state = new DebouncedFieldState(1, 500) // with delay: 500ms

对应地,FieldState 上的字段 _value 也被移除,因此绑定 UI 的方式会有调整:formstate-x v3 不再提供 bindInput;要将 state 与输入控件进行绑定,直接使用 state.value & state.onChange 即可。如:

<input
  value={state.value}
  onChange={e => state.onChange(e.target.value)}
/>

注意,若 stateDebouncedFieldState 实例 ,应当使用 state.$ 而不是 state 进行绑定(详见 Debounced State)。

3. FormState[mode=array] -> ArrayFormState

v2 的 FormState 支持 object / array 两种模式(mode),分别对应两种不同的使用姿势:

在 v3 中,第一种使用姿势与 v2 一致;对于第二种使用姿势(对应于输入是一个长度不定的列表的情况),我们单独提供了 ArrayFormState 来满足这样的场景:

const state = new ArrayFromState([foo, bar], createChildState)

ArrayFromState 的使用与原 FormState 也会有所区别,详见 Input List & #54

4. 其他

其他值得了解的变更

1. TranformedState

对于 UI value 与 business value 不一致的情况,我们过去通过由 Input 组件导出 getValue 来实现。在 v3 中,我们提供了 TranformedState 来处理这种诉求,它的好处是不会要求 Input 组件提供额外的导出(getValue),对 Input 组件的使用者也更友好(直接使用 state.value 即可),对应地,其可组合性也会更好。详见 Transformed State & #56

2. set & onChange

在 v2 中,仅 FieldState 实例提供了 set / onChange 来直接操作其 value;对于 FormState 实例,往往需要去通过其子 state(state.$.xxx)来实现对值的设置。在 v3 中,所有(实现了 IState 接口的)state 都会提供 onChange / set,其语义与 v2 中 FieldState 实例提供的 set / onChange 语义一致。因此你可以方便地在上层(父级 state)直接进行值的设置:

const state = new FormState({ foo: fooState, bar: barState })
state.set({ foo: 1, bar: 2 })

相比

state.$.foo.set(1)
state.$.bar.set(2)

state.set({ foo: 1, bar: 2 }) 的做法更简单,也使得上层与下层逻辑的耦合更低(父级 state 无须知道子 state 的信息)

3. ownError & hasOwnError

在 v3 中,仅 FormState 实例会提供 ownError & hasOwnError。现在所有(实现了 IState 接口的)state 实例都会提供 ownError & hasOwnError。建议使用 ownError & hasOwnError 代替 error & hasError 去实现校验结果与界面的绑定(如 bindFormItem),详见 #71

4. 阅读最新的文档

v3 提供了全新的文档( https://qiniu.github.io/formstate-x/ ),内容不长,建议阅读以便了解 formstate-x 中的关键概念

mattleonowicz commented 2 years ago

@nighca Nice to see this awesome library developed farther and farther! Is there any chance of translating whole release notes to english?

nighca commented 2 years ago

@mattleonowicz I will (in couple of days).

P.S. If currently you are not using any older versions of formstate-x, the release note here is not actually important. You can head to the documents directly :) That's much more detailed.

nighca commented 2 years ago

@mattleonowicz The en version is here. Feel free if any further questions.

mattleonowicz commented 2 years ago

Thank you! I'm still on v2. Will move to v3 soon