React form

来源

表单组件支持几个受用户交互影响的属性:

a. value,用于 <input><textarea> 组件。
b. checked,用于类型为 checkbox 或者 radio<input> 组件。
c. selected,用于 <option> 组件。

HTML 中,<textarea> 的值通过子节点设置;在 React 中则应该使用 value 代替。

表单组件可以通过 onChange 回调函数来监听组件变化。当用户做出以下交互时,onChange 执行并通过浏览器做出响应:

<input><textarea>value 发生变化时。
<input>checked 状态改变时。
<option>selected 状态改变时。

和所有 DOM 事件一样,所有的 HTML 原生组件都支持 onChange 属性,而且可以用来监听冒泡的 change 事件。


一、受限组件

设置了 value<input> 是一个受限组件。 对于受限的 <input>,渲染出来的 HTML 元素始终保持 value 属性的值。例如:

var FormClass = React.createClass({
    render: function () {
        return (
            <input type="text" value="Hello!"/>
        );
    }
});

React.render(
    <FormClass />,
    document.getElementById('demo1')
);

上面的代码将渲染出一个值为 Hello! 的 input 元素。用户在渲染出来的元素里输入任何值都不起作用,因为 React 已经赋值为 Hello!。 如果想响应更新用户输入的值,就得使用 onChange 事件:

var FormClass2 = React.createClass({
    getInitialState: function () {
        return {value: 'Hello!'};
    },
    handleChange: function (event) {
        this.setState({value: event.target.value});
    },
    render: function () {
        var value = this.state.value;
        return <input type="text" value={value} onChange={this.handleChange}/>;
    }
});

React.render(
    <FormClass2 />,
    document.getElementById('demo2')
);

上面的代码中,React 将用户输入的值更新到 <input> 组件的 value 属性。这样实现响应或者验证用户输入的界面就很容易了。例如:

handleChange: function(event) {
    this.setState({value: event.target.value.substr(0, 140)});
}

上面的代码接受用户输入,并截取前 140 个字符。


二、不受限组件

没有设置 value(或者设为 null) 的 <input> 组件是一个不受限组件。对于不受限的 <input> 组件,渲染出来的元素直接反应用户输入。例如:

var FormClass3 = React.createClass({
    render: function () {
        return <input type="text" />;
        //return <input type="text" defaultValue="Hello!"/>;
    }
});

React.render(
    <FormClass3 />,
    document.getElementById('demo3')
);

上面的代码将渲染出一个空值的输入框,用户输入将立即反应到元素上。和受限元素一样,使用 onChange 事件可以监听值的变化。

如果想给组件设置一个非空的初始值,可以使用 defaultValue 属性。例如:

render: function() {
    return <input type="text" defaultValue="Hello!" />;
}

上面的代码渲染出来的元素和受限组件一样有一个初始值,但这个值用户可以改变 并会反应到界面上

同样地, 类型为 radiocheckbox<input> 支持 defaultChecked 属性, <select> 支持 defaultValue 属性。

var FormClass4 = React.createClass({
    render: function () {
        var style = {marginTop: 10};

        return (
            <div>
                <input type="radio" name="opt"/> Option 1
                <input type="radio" name="opt" defaultChecked/> Option 2 <br/>
                <select defaultValue="C" style={style}>
                    <option value="A">Apple</option>
                    <option value="B">Banana</option>
                    <option value="C">Cranberry</option>
                </select>
            </div>
        );
    }
});

React.render(
    <FormClass4 />,
    document.getElementById('demo4')
);

三、高级主题

1、为什么使用受限组件?

React 中使用诸如 <input> 的表单组件时,遇到了一个在传统 HTML 中没有的挑战。
比如下面的代码:

    <input type="text" name="title" value="Untitled" />

HTML 中将渲染初始值为 Untitled 的输入框。用户改变输入框的值时,节点的 value 属性(property)将随之变化, 但是 node.getAttribute('value') 还是会返回初始设置的值 Untitled.

HTML 不同,React 组件必须在任何时间点描绘视图的状态,而不仅仅是在初始化时。比如在 React 中:

render: function() {
    return <input type="text" name="title" value="Untitled" />;
}

该方法在任何时间点渲染组件以后,输入框的值就应该始终为 Untitled。

2、为什么 使用 value 属性?

HTML 中, <textarea> 的值通常使用子节点设置:

 <!-- 反例:在 React 中不要这样使用! -->
 <textarea name="description">This is the description.</textarea>

HTML 而言,让开发者设置多行的值很容易。但是,ReactJavaScript,没有字符限制,可以使用 \n 实现换行。简言之,React 已经有 valuedefaultValue 属性,</textarea> 组件的子节点扮演什么角色就有点模棱两可了。基于此, 设置 <textarea> 值时不应该使用子节点:

<textarea name="description" value="This is a description." />

如果非要使用子节点,效果和使用 defaultValue 一样。


3、 为什么 使用 value 属性

HTML<select> 通常使用 <option>selected 属性设置选中状态;React 为了更方面的控制组件,采用以下方式代替:

 <select value="B">
     <option value="A">Apple</option>
     <option value="B">Banana</option>
     <option value="C">Cranberry</option>
 </select> 

如果是不受限组件,则使用 defaultValue

注意:
value 属性传递一个数组,可以选中多个选项:<select multiple={true} value={['B', 'C']}>

var FormClass5 = React.createClass({
    render: function () {
        var style = {marginTop: 10};

        /*<select multiple={true} defaultValue={['B','C']} style={style}>*/
        return (
            <div>
                <select multiple={true} value={['B','C']} style={style}>
                    <option value="A">Apple</option>
                    <option value="B">Banana</option>
                    <option value="C">Cranberry</option>
                </select>
            </div>
        );
    }
});

React.render(
    <FormClass5 />,
    document.getElementById('demo5')
);
### React 表单处理概述 React 中的表单处理可以通过受控组件(Controlled Components)和非受控组件(Uncontrolled Components)两种方式实现。其中,使用 Hook 的方法可以让开发者更加便捷地管理表单状态和交互逻辑[^2]。 #### 受控组件 (Controlled Component) 在受控组件中,表单输入元素的值由 React 状态管理,而不是由 DOM 元素本身决定。这种方式确保了 UI 始终与表单的状态同步。通过设置 `value` 属性并监听 `onChange` 事件来更新状态,可以轻松实现这一目标[^2]。 ##### 示例代码:使用 `useState` 处理单一输入框 ```javascript import React, { useState } from 'react'; function NameForm() { const [name, setName] = useState(''); function handleChange(event) { setName(event.target.value); } function handleSubmit(event) { alert('提交的名字: ' + name); event.preventDefault(); } return ( <form onSubmit={handleSubmit}> <label> 名字: <input type="text" value={name} onChange={handleChange} /> </label> <button type="submit">提交</button> </form> ); } export default NameForm; ``` 在此示例中,`NameForm` 组件通过 `useState` 钩子跟踪用户的输入变化,并在提交时显示当前值[^2]。 --- #### 使用对象存储多个字段的状态 当需要处理包含多个字段的复杂表单时,可以将整个表单的状态保存在一个对象中,从而减少重复代码。 ##### 示例代码:多字段表单 ```javascript import React, { useState } from 'react'; function MultiFieldForm() { const [formData, setFormData] = useState({ firstName: '', lastName: '' }); function handleChange(event) { const target = event.target; const value = target.value; const name = target.name; setFormData(prevState => ({ ...prevState, [name]: value })); } function handleSubmit(event) { alert( '提交的信息:\n' + `名字: ${formData.firstName}\n` + `姓氏: ${formData.lastName}` ); event.preventDefault(); } return ( <form onSubmit={handleSubmit}> <label> 名字: <input type="text" name="firstName" value={formData.firstName} onChange={handleChange} /> </label> <br /> <label> 姓氏: <input type="text" name="lastName" value={formData.lastName} onChange={handleChange} /> </label> <br /> <button type="submit">提交</button> </form> ); } export default MultiFieldForm; ``` 这段代码展示了如何使用一个对象来管理多个输入字段的状态,并动态更新对应的属性[^2]。 --- #### 非受控组件 (Uncontrolled Component) 虽然大多数情况下推荐使用受控组件,但在某些特定场景下也可以考虑非受控组件。在这种模式下,DOM 元素负责维护自己的状态,而 React 则通过 `ref` 获取其值。 ##### 示例代码:非受控组件 ```javascript import React, { useRef } from 'react'; function UncontrolledForm() { const inputRef = useRef(null); function handleSubmit(event) { alert('提交的名字: ' + inputRef.current.value); event.preventDefault(); } return ( <form onSubmit={handleSubmit}> <label> 名字: <input type="text" ref={inputRef} /> </label> <button type="submit">提交</button> </form> ); } export default UncontrolledForm; ``` 尽管这种方法较为简单,但它通常不如受控组件那样直观且易于调试[^3]。 --- #### 总结 React 提供了多种工具和技术帮助开发者高效地构建表单界面。无论是采用基于状态的受控组件还是依赖于原生 DOM 的非受控组件,都可以根据实际需求选择合适的方法。结合 Hooks 的灵活性,能够进一步增强用户体验的同时降低开发难度。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值