diff --git a/CHANGELOG.md b/CHANGELOG.md
index e0ab30755..607b315ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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)
diff --git a/components/cascader/Cascader.js b/components/cascader/Cascader.js
index 8a36eb9e3..71af10b7e 100644
--- a/components/cascader/Cascader.js
+++ b/components/cascader/Cascader.js
@@ -137,7 +137,7 @@ const Cascader = (props) => {
}
}
},
- [changeOnSelect, expandTrigger]
+ [changeOnSelect, expandTrigger, onChange, cascaderValue, popperShow]
)
const clearValue = useCallback(
diff --git a/components/form/Form.js b/components/form/Form.js
index 64b5a62ed..99b64c2d0 100644
--- a/components/form/Form.js
+++ b/components/form/Form.js
@@ -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'
@@ -19,7 +19,6 @@ const getClassNames = (props) => {
_className[`hi-form--readOnly`] = readOnly
return _className
}
-
const InternalForm = (props) => {
const {
children,
@@ -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: {},
@@ -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
diff --git a/components/form/FormReducer.js b/components/form/FormReducer.js
index 223127b4e..2d82dfb53 100644
--- a/components/form/FormReducer.js
+++ b/components/form/FormReducer.js
@@ -1,3 +1,5 @@
+import _ from 'lodash'
+
/* eslint-disable no-case-declarations */
export const FILEDS_INIT = 'FILEDS_INIT'
export const FILEDS_UPDATE = 'FILEDS_UPDATE'
@@ -5,30 +7,45 @@ 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()
diff --git a/docs/demo/form/section-check.jsx b/docs/demo/form/section-check.jsx
index 1dc4afaea..957c9706b 100644
--- a/docs/demo/form/section-check.jsx
+++ b/docs/demo/form/section-check.jsx
@@ -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,
@@ -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')
@@ -128,11 +178,21 @@ const code = [
}}
/>
+
+ {
+ console.log('change')
+ }}
+ data={this.state.options}
+ style={{ width: '100%' }}
+ />
+
+
diff --git a/docs/zh-CN/components/form.mdx b/docs/zh-CN/components/form.mdx
index e444731eb..d05528ae8 100755
--- a/docs/zh-CN/components/form.mdx
+++ b/docs/zh-CN/components/form.mdx
@@ -72,14 +72,14 @@ 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
@@ -87,7 +87,7 @@ import DemoUseForm from '../../demo/form/section-useForm.jsx'
| -------------- | ------------------------ | -------------------------------------------------- | ------------------------------------------------------------- | ------ |
| onValuesChange | 字段值更新时触发回调事件 | (changedValues: object, allValues: object) => void | changedValues: 改变的表单对象
allValues: 所有表单项对象 | - |
-### SchemaForm
+## SchemaForm
> 继承 Form API
@@ -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
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| --------------- | --------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------- | -------- |
@@ -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
@@ -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