Skip to content

Commit

Permalink
fix(@uform/react): Fix form controlled (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
janryWang authored Jul 14, 2019
1 parent e0ae0fb commit c12ecb9
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
1 change: 1 addition & 0 deletions docs/Examples/next/Detail.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const App = () => {
<Printer>
<SchemaForm
actions={actions}
onChange={values=>setState(values)}
initialValues={state.value}
editable={state.editable}
labelCol={7}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ export class Form {
})
}

public isDirtyValues(values: any) {
return !isEmpty(values) && !isEqual(this.state.values, values)
}

public setFieldState = (
path: Path | IFormPathMatcher,
callback?: () => void
Expand Down
63 changes: 57 additions & 6 deletions packages/react/src/__tests__/value.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import React from 'react'
import { render } from '@testing-library/react'
import SchemaForm, { Field, registerFormField, connect } from '../index'
import React, { useState } from 'react'
import { render, act } from '@testing-library/react'
import SchemaForm, {
Field,
registerFormField,
connect,
createFormActions
} from '../index'

registerFormField(
'test-string',
connect()(props => <div data-testid="value">{typeof props.value}</div>)
connect()(props => (
<React.Fragment>
<div data-testid="value">{props.value}</div>
<div data-testid="type-value">{typeof props.value}</div>
</React.Fragment>
))
)

test('default value', async () => {
Expand All @@ -16,7 +26,7 @@ test('default value', async () => {

const { getByTestId } = render(<Component />)
await sleep(33)
expect(getByTestId('value').textContent).toEqual('string')
expect(getByTestId('type-value').textContent).toEqual('string')
})

test('initialValues', async () => {
Expand All @@ -28,5 +38,46 @@ test('initialValues', async () => {

const { getByTestId } = render(<Component />)
await sleep(33)
expect(getByTestId('value').textContent).toEqual('string')
expect(getByTestId('type-value').textContent).toEqual('string')
})

test('controlled initialValues', async () => {
const actions = createFormActions()
let outerSetState
const Component = () => {
const [state, setState] = useState({
foo: '123'
})
outerSetState = values =>
act(() => {
setState(values)
})
return (
<SchemaForm
actions={actions}
onChange={outerSetState}
initialValues={state}
>
<Field name="foo" type="test-string" />
</SchemaForm>
)
}

const { getByTestId } = render(<Component />)
await sleep(33)
expect(getByTestId('type-value').textContent).toEqual('string')
await actions.setFieldState('foo', state => {
state.value = '321'
})
await actions.reset()
expect(getByTestId('value').textContent).toEqual('123')
await actions.setFieldState('foo', state => {
state.value = '321'
})
act(() => {
outerSetState({ foo: '123' })
})
await sleep(33)
expect(getByTestId('value').textContent).toEqual('123')
await sleep(33)
})
9 changes: 3 additions & 6 deletions packages/react/src/state/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,11 @@ export const StateForm = createHOC((options, Form) => {

public componentDidUpdate(prevProps) {
const { value, editable, initialValues } = this.props
if (!isEmpty(value) && !isEqual(value, prevProps.value)) {
if (this.form.isDirtyValues(value)) {
this.form.changeValues(value)
}
if (
!isEmpty(initialValues) &&
!isEqual(initialValues, prevProps.initialValues)
) {
this.form.initialize({ initialValues })
if (this.form.isDirtyValues(initialValues)) {
this.form.initialize({ values: initialValues })
}
if (!isEmpty(editable) && !isEqual(editable, prevProps.editable)) {
this.form.changeEditable(editable)
Expand Down

0 comments on commit c12ecb9

Please sign in to comment.