---
order: 20
zh-CN:
	title: 订阅表单值更新
	name: 姓名
	address: 地址
	stature: 身高
	weight: 体重
	height: 身高
	hobbies: 爱好
	reading: 看书
	add: 增加爱好
en-US:
	title: Subscribe Observable Value
	name: Name
	address: Address
	stature: Stature
	weight: Weight
	height: Height
	hobbies: Hobbies
	reading: Reading
	add: Add Hobby
---

```jsx
import {
	Form,
	FormError,
	FormStrategy,
	FormControl,
	Input,
	Validators,
	FieldSet,
	FormInputField,
	Button,
	Notify,
	Icon,
} from 'zent';

const { useState, useEffect, useCallback } = React;
const { useForm, useFieldArray, useFormValue } = Form;

function App() {
	const form = useForm(FormStrategy.View);

	return (
		<Form form={form} layout="vertical">
			<FormInputField required name="name" label="{i18n.name}" />
			<FormInputField name="address" label="{i18n.address}" />
			<FieldSet name="stature">
				<FormInputField name="weight" label="{i18n.weight}" />
				<FormInputField name="height" label="{i18n.height}" />
			</FieldSet>
			<FieldArray />
			<Preview form={form} />
		</Form>
	);
}

function FieldArray() {
	const model = useFieldArray('hobbies', [], ['{i18n.reading}']);
	model.destroyOnUnmount = true;

	return (
		<FormControl label="{i18n.hobbies}">
			{model.children.map((child, index) => {
				return (
					<div key={child.id}>
						<FormInputField
							withoutLabel
							model={child}
							props={{
								addonAfter: (
									<Icon
										type="close"
										style={{ cursor: 'pointer' }}
										onClick={() => model.splice(index, 1)}
									/>
								),
							}}
						/>
					</div>
				);
			})}
			<Button type="primary" onClick={() => model.push('')}>
				{i18n.add}
			</Button>
		</FormControl>
	);
}

function Preview({ form }) {
	// You will see a warning about performance issues in console.
	// Only do this if you know what you are doing.
	const value = useFormValue(form);

	return (
		<>
			<div>Form Value</div>
			<pre>{JSON.stringify(value, null, 2)}</pre>
		</>
	);
}

ReactDOM.render(<App />, mountNode);
```
