Skip to content

Commit

Permalink
fix: #1408
Browse files Browse the repository at this point in the history
  • Loading branch information
Wugaoliang committed Dec 9, 2020
1 parent aedf062 commit 345a814
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 59 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# 更新日志

## 3.2.1

- 修复 `Form` 在页面渲染完成后 调用中 setFieldsValue 无效问题 [#1408](https://github.com/XiaoMi/hiui/issues/1408)

## 3.2.0

- 新增 HiUI 基础样式 css 文件 [#1338](https://github.com/XiaoMi/hiui/issues/1338)
Expand Down
2 changes: 1 addition & 1 deletion components/cascader/Cascader.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const Cascader = (props) => {
}
}
},
[changeOnSelect, expandTrigger]
[changeOnSelect, expandTrigger, onChange, cascaderValue, popperShow]
)

const clearValue = useCallback(
Expand Down
7 changes: 3 additions & 4 deletions components/form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useCallback, useReducer, forwardRef } from 'react'
import _ from 'lodash'
import classNames from 'classnames'
import PropTypes from 'prop-types'
import FormReducer, { FILEDS_UPDATE, FILEDS_UPDATE_LIST } from './FormReducer'
import Immutable, { FILEDS_UPDATE, FILEDS_UPDATE_LIST } from './FormReducer'
import FormContext from './FormContext'
import { transformValues } from './utils'

Expand All @@ -19,7 +19,6 @@ const getClassNames = (props) => {
_className[`hi-form--readOnly`] = readOnly
return _className
}

const InternalForm = (props) => {
const {
children,
Expand All @@ -30,7 +29,7 @@ const InternalForm = (props) => {
onValuesChange,
_type // SchemaForm 内部配置变量
} = props
const [state, dispatch] = useReducer(FormReducer, {
const [state, dispatch] = useReducer(Immutable.FormReducer, {
fields: [],
listNames: [],
listValues: {},
Expand All @@ -41,7 +40,7 @@ const InternalForm = (props) => {
// 用户手动设置表单数据
const setFieldsValue = useCallback(
(values) => {
const _fields = _.cloneDeep(fields)
const _fields = Immutable.currentStateFields()
_fields.forEach((item) => {
const { field } = item
// eslint-disable-next-line no-prototype-builtins
Expand Down
65 changes: 41 additions & 24 deletions components/form/FormReducer.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
import _ from 'lodash'

/* eslint-disable no-case-declarations */
export const FILEDS_INIT = 'FILEDS_INIT'
export const FILEDS_UPDATE = 'FILEDS_UPDATE'
export const FILEDS_UPDATE_VALUE = 'FILEDS_UPDATE_VALUE'
export const FILEDS_REMOVE = 'FILEDS_REMOVE'
export const FILEDS_INIT_LIST = 'FILEDS_INIT_LIST'
export const FILEDS_UPDATE_LIST = 'FILEDS_UPDATE_LIST'
const FormReducer = (state, action) => {
switch (action.type) {
case FILEDS_INIT:
const { fields } = state
const initfields = [...fields].filter((item) => {
return action.payload.field !== item.field
})
return Object.assign({}, { ...state }, { fields: initfields.concat(action.payload) })
case FILEDS_UPDATE:
return Object.assign({}, { ...state }, { fields: [...action.payload] })
case FILEDS_REMOVE:
const _fields = state.fields.filter((item) => {
return action.payload !== item.field && action.payload !== item.propsField
})
return Object.assign({}, { ...state }, { fields: _fields })
class Immutable {
constructor() {
this.state = {}
}

FormReducer = (state, action) => {
switch (action.type) {
case FILEDS_INIT:
const { fields } = state
const initfields = [...fields].filter((item) => {
return action.payload.field !== item.field
})
this.state = Object.assign({}, { ...state }, { fields: initfields.concat(action.payload) })
return this.state
case FILEDS_UPDATE:
return Object.assign({}, { ...state }, { fields: [...action.payload] })
case FILEDS_REMOVE:
const _fields = state.fields.filter((item) => {
return action.payload !== item.field && action.payload !== item.propsField
})
this.state = Object.assign({}, { ...state }, { fields: _fields })
return this.state
case FILEDS_INIT_LIST:
const { listNames } = state
!listNames.includes(action.payload) && listNames.push(action.payload)
this.state = Object.assign({}, { ...state }, { listNames: listNames })

return this.state
case FILEDS_UPDATE_LIST:
this.state = Object.assign({}, { ...state }, { listValues: action.payload })
return this.state
default:
this.state = state
return state
}
}

case FILEDS_INIT_LIST:
const { listNames } = state
!listNames.includes(action.payload) && listNames.push(action.payload)
return Object.assign({}, { ...state }, { listNames: listNames })
case FILEDS_UPDATE_LIST:
return Object.assign({}, { ...state }, { listValues: action.payload })
default:
return state
currentStateFields() {
return _.cloneDeep(this.state.fields)
}
}
export default FormReducer
export default new Immutable()
62 changes: 61 additions & 1 deletion docs/demo/form/section-check.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,56 @@ const code = [
store:''
},
checkedIndex: -1,
options: [
{
id: '手机',
content: '手机',
children: [
{
id: '小米',
content: '小米',
children: [
{
id: '小米3',
content: '小米3'
},
{
id: '小米4',
content: '小米4'
},
]
},
{
id: '红米',
content: '红米',
children: [
{
id: '红米3',
content: '红米3'
},
{
id: '红米4',
content: '红米4'
}
]
}
]
},
{
id: '电视',
content: '电视',
children: [
{
id: '小米电视4A',
content: '小米电视4A'
},
{
id: '小米电视4C',
content: '小米电视4C'
}
]
}
],
rules: {
name: {
required: true,
Expand Down Expand Up @@ -65,7 +115,7 @@ const code = [
handleSubmit() {
this.form.current.validate((valid,error) => {
console.log(valid,error)
console.log('valid:',valid,'error:',error)
if(!error) {
console.log(valid)
alert('submit')
Expand Down Expand Up @@ -128,11 +178,21 @@ const code = [
}}
/>
</FormItem>
<FormItem label='品类' field='category'>
<Cascader
onChange={(id)=>{
console.log('change')
}}
data={this.state.options}
style={{ width: '100%' }}
/>
</FormItem>
<FormItem label='地区' field='region'>
<Radio.Group
data={['北京', '上海', '重庆']}
/>
</FormItem>
<FormItem>
<Button type='primary' onClick={this.handleSubmit.bind(this)}>提交</Button>
<Button type='line' onClick={this.cancelSubmit.bind(this)}>重置</Button>
Expand Down
58 changes: 29 additions & 29 deletions docs/zh-CN/components/form.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,22 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'

### Form

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------------- | ------------------------------------------------------------------------------------- | ------- | -------------------------- | ---------- |
| initialValues | 表单默认值,只有初始化以及重置时生效 | object | - | - |
| rules | 表单验证规则,用法参考 [async-validator](https://github.com/yiminghe/async-validator) | object | - | - |
| labelWidth | label 宽度,可用任意 CSS 长度单位 | string | |
| labelPlacement | label 放置的位置 | string | 'right' \| 'left' \| 'top' | 'left' |
| placement | 是否横向排列 | string | 'horizontal' \| 'vertical' | 'vertical' |
| showColon | 是否显示冒号 | boolean | true \| false | true |
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------------- | ---------------------------------------------------------------------------------------- | ------- | -------------------------- | ---------- |
| initialValues | 表单默认值,只有初始化以及重置时生效;该值是不受控的,和表单中的 defaultValue 的作用相同 | object | - | - |
| rules | 表单验证规则,用法参考 [async-validator](https://github.com/yiminghe/async-validator) | object | - | - |
| labelWidth | label 宽度,可用任意 CSS 长度单位 | string | |
| labelPlacement | label 放置的位置 | string | 'right' \| 'left' \| 'top' | 'left' |
| placement | 是否横向排列 | string | 'horizontal' \| 'vertical' | 'vertical' |
| showColon | 是否显示冒号 | boolean | true \| false | true |

## Events

| 名称 | 说明 | 类型 | 参数 | 返回值 |
| -------------- | ------------------------ | -------------------------------------------------- | ------------------------------------------------------------- | ------ |
| onValuesChange | 字段值更新时触发回调事件 | (changedValues: object, allValues: object) => void | changedValues: 改变的表单对象 <br/> allValues: 所有表单项对象 | - |

### SchemaForm
## SchemaForm

> 继承 Form API
Expand All @@ -97,14 +97,14 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'
| submit | 继承 Form.Submit API | Object | - | - |
| reset | 继承 Form.Reset API | Object | - | - |

### FormList
## FormList

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------- | -------- | ---------------------------------------------------------------- | ------ | ------ |
| name | 列表名称 | String | - | - |
| children | 渲染函数 | (fields: Field[], operation: { add, remove }) => React.ReactNode | - | - |

### Form.Item
## Form.Item

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| --------------- | --------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------- | -------- |
Expand All @@ -117,7 +117,7 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'
| valuePropName | 子节点的值的属性,如 Switch Radio Checkbox 的是 'checked' | string | - | 'value' |
| contentPosition | 指定显示内容的位置的位置,对一些非 HiUI 表单组件进行设置 | string | 'top' \| 'center' \|'bottom' | 'center' |

### SchemaItem
## SchemaItem

> 继承 Form.Item API
Expand All @@ -126,33 +126,33 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'
| component | 用于渲染的组件名称,(现在组件名称,只限于 HiUI 中的组件名) | string | - | - |
| componentProps | 组件的属性 | string | - | - |

### Form.Submit
## Form.Submit

> 继承 Button API
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------- | -------------------------------------------------------------- | -------- | ------ | --------- |
| onClick | 点击提交后触发 Function(value: Object, errors: Object) => void | Function | - | func.noop |
| validate | 需要校验的 field 数组 | Array | - | - |
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------- | -------------------------------------------------------------- | -------- | ------ | --------- |
| onClick | 点击提交后触发 Function(value: Object, errors: Object) => void | Function | - | func.noop |
| fields | 需要校验的 field 字段,不传入的话就是默认全部校验 | Array | - | - |

### Form.Reset
## Form.Reset

> 继承 Button API
| 参数 | 说明 | 类型 | 默认值 |
| --------- | ------------------------- | -------- | --------- |
| onClick | 点击提交后触发 () => void | Function | func.noop |
| fields | 自定义重置的字段 | Array | - |
| toDefault | 返回默认值 | Boolean | true |
| 参数 | 说明 | 类型 | 默认值 |
| --------- | ------------------------------------------------- | -------- | --------- |
| onClick | 点击提交后触发 () => void | Function | func.noop |
| fields | 需要重置的 field 字段,不传入的话就是默认全部重置 | Array | - |
| toDefault | 返回默认值 | Boolean | true |

## Methods

| 方法名 | 说明 |
| ------------------------------------------------------ | ------------------ |
| validate(callback: isValid => void) | 对整个表单进行校验 |
| validateField(field: string, callback: errors => void) | 对表单字段进行校验 |
| resetValidates() | 重置整个表单的验证 |
| setFieldsValue() | 设置表单的值 |
| 方法名 | 说明 |
| -------------------------------------------------------------------------- | ------------------------------------------------------------ |
| validate(callback: (fields: Object, errors: Object) => void, fields:Array) | 对整个表单进行校验, 对应 [Form.Submit](#Form.Submit)中的 API |
| validateField(fields: string, callback: errors => void) | 对指定表单字段进行校验 |
| resetValidates(callback:() => void, fields:Array, toDefault:boolean) | 重置整个表单的验证,对应 [Form.Reset](#Form.Reset)中的 API |
| setFieldsValue(field: Object) | 设置表单的值,在异步获取的数据回显的时候,使用该方法 |

## rules

Expand Down

0 comments on commit 345a814

Please sign in to comment.