React官方文档--Forms

Forms

表单组件,比如:<input><textarea><option>和基本的组件不同,因为表单组件是需要用户进行交互的。这些组件提供了接口,用来更容易的管理表单来响应用户的交互。
有两种形式的表单组件
1. Controlled Components
2. Uncontrolled Components

Controlled Components

一个受控表单组件提供一个value属性,一个受控表单组件不会维持其内部自己的状态,组件只根据props进行渲染。

render() {
    return (
        <input
            type="text"
            value="Hello!"
        />
    )
}

如果你试图去运行这里例子,会发现输入框里的内容不会随着输入而改变。因为你声明了这个组件的value值,为了更新value作为用户输入的响应,需要添加onChange事件来保存新的值,然后传递这个值给value属性。

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value:""
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        console.log("Text field value is : " + this.state.value);
    }

    render() {
        return (
            <div>
                <input type="text" placeholder="Hello!"
                value={this.state.value} onChange={this.handleChange}/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

在这个例子中,我们接受用户提供的值,来更新value 的值,这种方法使得继承接口或者进行表单验证变得很方便

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

Checkboxes和RadioButton存在的潜在问题

在使用React来监听checkbox或者radio的事件的时候,React监听一个click的浏览器事件来声明一个onChange事件,在大部分情况下这样是没有什么问题的,除非当你调用了preventDefault()在change的事件处理函数里面,preventDefault会停止浏览器在视觉上更新输入,即使checked的值已经改变了,这个问题可以通过不调用preventDefault或者将切换checked的值放在setTimeout中执行来解决。

非受控组件

不提供value属性的表单组件称为非受控组件。下面的例子渲染了一个<input>来控制一个空的值,任何用户输入的值会立刻影响到渲染的元素。
一个非受控组件管理他自己的状态。

render() {
    return <input type="text" />
}

如果你希望监听这个组件的值的更新,你需要使用onChange事件来监听,就像受控组件一样,但是不能给组件传递任何值。

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ''
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        alert("Text field value is : " + this.state.value);
    }

    render() {
        return (
            <div>
                <input 
                    type="text"
                    placeholder="Hello!"
                    onChange={this.handleChange} />
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        );
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
)

当这个例子输入value的时候,我们可以通过handleSubmit()来读取,非受控表单组件不能够请求,你需要完整的onChange事件处理来取代读取value

默认值

使用一个非空的value来初始化一个非受控组件,你可以使用一个defaultValue属性

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

同样地,<input type="checkbox"><input type="radio">支持defaultChecked然后<select>支持defaultValue

交互属性

表单组件支持一系列的props会通过用户交互影响组件。
1. value,是<input><textarea>支持的组件。
2. checked,是<input>组件的checkboxradio支持的
3. selected,是<option>组件支持的。
在HTML中,<textarea>的值是通过子元素来设置的,在React中,需要使用value来替代
表单组件允许通过onChange属性的回调函数来监听修改,onChange属性通过浏览器和用户交互的响应。

进阶技术

为什么使用受控组件

使用类似<input>的表单组件是和传统的HTML不相同的。

<input type="text" name="title" value="Untitle">

上面的代码渲染初始化了一个value为Untitle。当用户更新输入的时候,这个节点的value属性也会改变,然而使用node.getAttribute('value')仍然会返回初始化的时候的值:Untitled
与HTML不同的是,React组件必须一致保持其状态,也就是自从渲染之后,value的值一直保持为Untitled

Why Textarea Value

在HTML,<textarea>的值应该是其子元素的值。

<textarea name="description">This is the description.</textarea>

在HTML中,很容易允许开发人员提供多行的值,然而,在React中,我们不能够设置多行的字符串,如果要换行的话需要使用\n,在有value和defaultValue的时候,因为这个原因,你不需要使用子元素来设置<textarea>的值。

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

Why Select Value

option<select>中是用selected属性来进行判断选择的,但是在React的组件中,是使用value属性的。

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

使用非受控组件的话,这里需要使用defaultValue

受控输入框

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = { value: '' };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        alert('Text field value is: ' + this.state.value);
    }

    render() {
        return (
            <div>
                <input
                type="text"
                placeholder="edit me"
                value={this.state.value}
                onChange={this.handleChange}
                />
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        );
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById('root')
);

受控文本区组件

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ""
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        alert("Textarea value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <textarea
                    name="description"
                    value={this.state.value}
                    onChange={this.handleChange}
                />
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

受控下拉列表

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ""
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        alert("Select value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <select value={this.state.value} onChange={this.handleChange}>
                    <option value="A">Apple</option>
                    <option value="B">Banana</option>
                    <option value="C">Cranberry</option>
                </select>
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

非受控单选按钮

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: "B"
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    handleSubmit(event) {
        alert("Radio button value is: " + this.state.value);
    }

    render() {
        return (
            <div>
                <label>
                    <input type="radio" name="choice" value="A" onChange={this.handleChange}/>
                    Option A
                </label>
                <label>
                    <input type="radio" name="choice" value="B" onChange={this.handleChange}/>
                    Option B
                </label>
                <label>
                    <input type="radio" defaultChecked={true} name="choice" value="C" onChange={this.handleChange}/>
                    Option C
                </label>
                <br/>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);

非受控复选框

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            checked: {
                'A': false,
                'B': true,
                'C': false
            }
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        const value = event.target.value;

        const checked = Object.assign({}, this.state.checked);
        if (!checked[value]) {
            checked[value] = true;
        } else {
            checked[value] = false;
        }
        this.setState({checked});
    }

    handleSubmit(event) {
        alert("Boxes checked: " + 
            (this.state.checked.A ? 'A ' : ' ') +
            (this.state.checked.B ? 'B ' : ' ') +
            (this.state.checked.C ? 'C ' : ' ')
        );
    }

    render() {
        return (
            <div>
                <label>
                    <input type="checkbox" value="A" onChange={this.handleChange} />
                    Option A
                </label>
                <label>
                    <input type="checkbox" value="B" onChange={this.handleChange} defaultChecked={true}/>
                    Option B
                </label>
                <label>
                    <input type="checkbox" value="C" onChange={this.handleChange} />
                    Option C
                </label>
                <button onClick={this.handleSubmit}>
                    Submit
                </button>
            </div>
        )
    }
}

ReactDOM.render(
    <Form />,
    document.getElementById("root")
);      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值