Skip to content

Commit

Permalink
fix(@uform/core): fix setFormState Promise resolve is not wait rerend…
Browse files Browse the repository at this point in the history
…er completed.
  • Loading branch information
janryWang committed Apr 26, 2019
1 parent d9523eb commit d9a24d4
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 14 deletions.
37 changes: 23 additions & 14 deletions packages/core/src/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
caf,
isChildField,
getSchemaNodeFromPath,
BufferList
BufferList,
defer
} from './utils'
import { Field } from './field'
import { runValidation, format } from '@uform/validator'
Expand Down Expand Up @@ -166,24 +167,21 @@ export class Form {

setFormState = reducer => {
if (!isFn(reducer)) return
return new Promise(resolve => {
const published = this.publishState()
reducer(published, reducer)
this.checkState(published)
resolve()
})
const published = this.publishState()
reducer(published, reducer)
return Promise.resolve(this.checkState(published))
}

checkState(published) {
if (!isEqual(this.state.values, published.values)) {
this.state.values = published.values
this.state.dirty = true
this.updateFieldsValue()
return this.updateFieldsValue()
}
if (!isEqual(this.state.initialValues, published.initialValues)) {
this.state.initialValues = published.initialValues
this.state.dirty = true
this.updateFieldInitialValue()
return this.updateFieldInitialValue()
}
}

Expand Down Expand Up @@ -438,20 +436,29 @@ export class Form {
}

updateFieldsValue(validate = true) {
const { promise, resolve } = defer()

const update = () => {
const updateList = []
each(this.fields, (field, name) => {
let newValue = this.getValue(name)
field.updateState(state => {
state.value = newValue
})
if (field.dirty) {
raf(() => {
if (this.destructed) return
field.notify()
this.triggerEffect('onFieldChange', field.publishState())
})
updateList.push(
new Promise(resolve => {
raf(() => {
if (this.destructed) return
field.notify()
this.triggerEffect('onFieldChange', field.publishState())
resolve()
})
})
)
}
})
resolve(Promise.all(updateList))
}
if (this.state.dirty && this.initialized) {
if (validate) {
Expand All @@ -463,6 +470,8 @@ export class Form {
update()
}
}

return promise
}

updateChildrenVisible(parent, visible) {
Expand Down
28 changes: 28 additions & 0 deletions packages/react/src/__tests__/actions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import SchemaForm, {
Field,
registerFormField,
connect,
createAsyncFormActions
} from '../index'
import { render } from 'react-testing-library'

beforeEach(() => {
registerFormField('string', connect()(props => <div>{props.value}</div>))
})

test('createFormActions', async () => {
const actions = createAsyncFormActions()
const TestComponent = () => (
<SchemaForm actions={actions}>
<Field name='aaa' type='string' />
</SchemaForm>
)

const { queryByText } = render(<TestComponent />)
await sleep(33)
await actions.setFormState(state => (state.values = { aaa: 123 }))
expect(queryByText('123')).toBeVisible()
await actions.setFieldState('aaa', state => (state.value = 'hello world'))
expect(queryByText('hello world')).toBeVisible()
})
13 changes: 13 additions & 0 deletions packages/utils/src/defer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const defer = () => {
let _resolve
let _reject
const promise = new Promise((resolve, reject) => {
_resolve = resolve
_reject = reject
})
return {
promise,
resolve: _resolve,
reject: _reject
}
}
1 change: 1 addition & 0 deletions packages/utils/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './schema'
export * from './lru'
export * from './isEmpty'
export * from './case'
export * from './defer'

0 comments on commit d9a24d4

Please sign in to comment.