第一部分:表单基础

在React中,修改表单的唯一途径是使用setState方法。举例如下:

  

class NameForm 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('A name was submitted: ' + this.state.value);
event.preventDefault();
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
} ReactDOM.render(
<NameForm />,
document.getElementById('root')
);

  在codepen的运行代码连接

  

  我们可以看出其运行逻辑:首先将组建渲染到页面,及执行了render(),此时获取的value为空,当我们输入数据时,触发handleChange函数(注意:要提前绑定在当前环境下),然后设置state中的value为用户当前输入值,于是表单元素input获取到最新的state并使用虚拟dom与真实dom作对比,只更新有变化的dom...  当点击提交按钮时,触发了handleSubmit函数。

  值得注意的是:在handleSubmit函数中,我们使用event.preventDefault()阻止了默认行为,即:提交表单后,不会自动reset表单,而是保留之前的用户数据!

第二部分:textarea表单

  textarea表单和Input表单本身是没有什么区别的,举例如下所示:

class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Please write an essay about your favorite DOM element.'
}; this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
} handleChange(event) {
this.setState({value: event.target.value});
} handleSubmit(event) {
alert('An essay was submitted: ' + this.state.value);
event.preventDefault();
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<textarea value={this.state.value} onChange={this.handleChange} style={{color:'red',width:'400px',height:'15px'}} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
} ReactDOM.render(
<EssayForm/>,
document.getElementById('root')
);

  这里我设置了初始状态,所以一开始我们就可以在textarea中看到内容,稍有不同的是,我还在textarea中设置了样式(注意:要用两个curly brace,外面的表示包含js对象,里面的表示包含一个样式对象,当然我们也可以在外面先定义对象然后再传进来)。

  另外,我们还可以直接在css中设置样式,如下所示:

textarea{
background:red;
color:white !important;
}

  这样,背景颜色为红色,字体为白色。

  注意:因为在React中设置的style是行内样式,优先级较高,故在外联样式中无法覆盖,只有通过使用!important的方式才能成功覆盖。

  另外,将样式对象传入的方法如下:

render() {
var myStyle = {
width:'400px',
height:'15px',
color:'red'
};
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<textarea value={this.state.value} onChange={this.handleChange} style={myStyle} />
</label>
<input type="submit" value="Submit" />
</form>
);

第三部分:select表单

  例子如下所示:

class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'}; this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
} handleChange(event) {
this.setState({value: event.target.value});
} handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
} ReactDOM.render(
<FlavorForm />,
document.getElementById('root')
);

连接。

第四部分:复杂表单

   举例如下所示:

class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests:
}; this.handleInputChange = this.handleInputChange.bind(this);
} handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name; this.setState({
[name]: value
});
} render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
} ReactDOM.render(
<Reservation />,
document.getElementById('root')
);

连接

第五部分:lifting state up

  举例如下:

const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
}; class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {value: ''};
} handleChange(e) {
this.setState({value: e.target.value});
} render() {
const value = this.state.value;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={value}
onChange={this.handleChange} />
</fieldset>
);
}
} class Calculator extends React.Component {
render() {
return (
<div>
<TemperatureInput scale="c" />
<TemperatureInput scale="f" />
</div>
);
}
} ReactDOM.render(
<Calculator />,
document.getElementById('root')
);

链接。

两个input联动

const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
}; function toCelsius(fahrenheit) {
return (fahrenheit - ) * / ;
} function toFahrenheit(celsius) {
return (celsius * / ) + ;
} function tryConvert(value, convert) {
const input = parseFloat(value);
if (Number.isNaN(input)) {
return '';
}
const output = convert(input);
const rounded = Math.round(output * ) / ;
return rounded.toString();
} function BoilingVerdict(props) {
if (props.celsius >= ) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
} class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
} handleChange(e) {
this.props.onChange(e.target.value);
} render() {
const value = this.props.value;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={value}
onChange={this.handleChange} />
</fieldset>
);
}
} class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {value: '', scale: 'c'};
} handleCelsiusChange(value) {
this.setState({scale: 'c',value});
} handleFahrenheitChange(value) {
this.setState({scale: 'f',value});
} render() {
const scale = this.state.scale;
const value = this.state.value;
const celsius = scale === 'f' ? tryConvert(value, toCelsius) : value;
const fahrenheit = scale === 'c' ? tryConvert(value, toFahrenheit) : value; return (
<div>
<TemperatureInput
scale="c"
value={celsius}
onChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
value={fahrenheit}
onChange={this.handleFahrenheitChange} />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
} ReactDOM.render(
<Calculator />,
document.getElementById('root')
);

链接

  

 值得注意的是: 如果几个组件都需要访问(获取)相同的state, 那么这是一个我们需要将state提升(listing)到他们几个共同的相同的祖先组件中的信号!在我们的例子中,就是Calculator。 我们存储了value 和 scale 在Calculator的state中。

 两个input将会保持同步,因为他们基于相同的state。

 不管你在哪个input中输入,this.state.value和this.state.scale都会更新。

 即通常,如果一个组件需要state来render,这时我们可以将之添加到这个组件中,但是如果另外一个组件也需要这个state,我们就可以把这个state提升到两者最近的祖先中去。相反于尝试着去同步两个不同组件的state,我们应当依赖于top-down data flow,即React中独特的自上而下的数据流。

  入门react不得不看的例子。

React之表单的更多相关文章

  1. 【09】react 之 表单组件

    不太清楚有多少初学React的同学和博主当时一样,在看完React的生命周期.数据流之后觉得已经上手了,甩开文档啪啪啪的开始敲了起来.结果...居然被一个input标签给教做人了. 故事是这样的:首先 ...

  2. 前端笔记之React(二)组件内部State&React实战&表单元素的受控

    一.组件内部的State 1.1 state state叫状态,是每一个类式组件都有的属性,但函数式组件,没有state. state是一个对象,什么值都可以定义. 在任何类式组件的构造函数中,可以用 ...

  3. react Input 表单

    ​ input react 表单 input 密码框在谷歌浏览器下 会有黄色填充 官网的不太用,这个比较好用 type="password" autoComplete=" ...

  4. react.js 表单验证-登录框

    import React,{ Component } from 'react'; import style from 'cms.css'; ​ /** * 路由路径 登录成功后页面跳转到index * ...

  5. react dva 表单校验

    import React,{ Component } from 'react'; import { connect } from 'dva'; import { WhiteSpace,NavBar , ...

  6. react 表单

    import React ,{PropTypes}from 'react'; import { render } from 'react-dom'; const styles={ mb10:{ mar ...

  7. react引用antd的form表单

    引用form是第三方插件ant插件,官网网址:https://ant.design/.用到的antd的版本是@2.0.1.form(https://ant.design/components/form ...

  8. 群里分享的react的收藏一下!今日周末,改了个表单验证然后无所事事了!

    今日周末,改了个表单验证然后无所事事了,然后把昨天群里分享的react的收藏一下尽管现在还在研究angular和nodeJs毕竟刚刚开始用有点不熟...没准以后会研究一下react毕竟看着下面这张图还 ...

  9. React表单元素的使用

    一. <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF ...

随机推荐

  1. github push403错误的处理

    如果没有什么别的问题的话,推荐使用SSH的方式.请参考:http://stackoverflow.com/questions/7438313/pushing-to-git-returning-erro ...

  2. swift - tableView数据向上收缩动画

    // //  TTTableViewController.swift //  tableVIewAnimation // //  Created by su on 15/12/11. //  Copy ...

  3. in操作符

    // Arrays,数组:下标 in array,length也可以 var trees = new Array("redwood", "bay", " ...

  4. 【树状DP】星象仪

    题目描述 在寂寞的夜里,星象仪是非常浪漫的东西.但是,你作为一个精神稍微有点不太正常的Geek,把原本正常的星象仪改造得像电报发送器一样.当然,你这个的构造还要更加奇葩一点.具体来说,你的星象仪是一棵 ...

  5. Python学习-11.Python中的类定义

    Python是一门面向对象语言,那么作为面向对象的特征——类也是有的.值得注意的是Python中一切皆对象,并不像C#中为了性能考虑,int这些在Python中也是对象.(C#中int是结构体) 如何 ...

  6. 修改TFS附件大小的限制

    在TFS服务器使用浏览器上打开如下地址:http://localhost:8080/tfs/<CollectionName>/WorkItemTracking/v1.0/Configura ...

  7. Ultimate guide to learning AngularJS in one day

    What is AngularJS? Angular is a client-side MVC/MVVM framework built in JavaScript, essential for mo ...

  8. mysql 主从日志文件mysql-bin文件清除方法

    默认情况下mysql会一直保留mysql-bin文件,这样到一定时候,磁盘可能会被撑满,这时候是否可以删除这些文件呢,是否可以安全删除,是个问题,不建议使用rm命令删除,这样有可能会不安全,正确的方法 ...

  9. C#基础笔记(第二十天)

    1.复习属性:保护字段的构造函数:初始化对象初始化对象:给对象的每个属性去赋值什么时候会调用构造函数:当我们new的时候面向对象中需要注意的两个关键字this 1.代表当前类的对象 2.调用自己的构造 ...

  10. 【ocp-12c】最新Oracle OCP-071考试题库(47题)

    47.(10-6)choose two You need to calculate the number of days from 1st January 2007 till date. Dates ...