第一部分:表单基础

在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. InstaGAN: Instance-Aware Image-to-Image Translation

  2. .NET基础 (15)委托

    委托1 请解释委托的基本原理2 委托回调静态方法和实例方法有何区别3 什么是链式委托4 链式委托的执行顺序是怎么样的5 可否定义拥有返回值的方法的委托链6 委托通常可以应用在哪些场合 委托1 请解释委 ...

  3. Linq编译带来的诡异错误

    今天遇到一个很诡异的问题,初步猜测是Linq编译以及编译器自动优化带来的原因,对IL不是很熟悉,所以懒得去追了. 贴个代码出来,希望能抛砖引玉,得到正解. 注意到我用原始的foreach语句代替了li ...

  4. 使用memset初始化C++自定义类型

    当类型本身或者类型的成员变量带有虚函数以及像std::vector这类复杂数据结构的时候.就会出错,原因是memset把类型本身所带的一些隐含的信息也给置0了.如:虚表指针.std::vector的内 ...

  5. Android-Activity启动模式-应用场景

    在上一篇博客中,Android-Activity启动模式(launchMode),就介绍了Activity四种启动模式的特点与使用等,但是到底什么样子的场景,去使用什么样子的启动模式呢 Activit ...

  6. Android-SqliteSQL语句大全

    SqliteSQL语句大全 创表语句: create table student_table(_id integer primary key autoincrement, name text, age ...

  7. linux服务器下配置多tomcat

    车辆交易用的系统模块,正在做.老板要看看,以便车城那边的人提出意见.于是在服务器上再次增加一个tomcat. 以前是配置过的,配置过程其实很简单,这次太大意了,找了半天问题. 首先是拷贝一个tomca ...

  8. struts2拦截器demo

    按照网上的一些资料配置的,期间也出现过几个错误. 其中有个错误,是关于struts.xml里面package配置的问题,因为里面的几个标签是有顺序的. 顺序是: result-types interc ...

  9. 如何将本地数据库迁移至SQL Azure

    Windows Azure的SQL Azure和SQL Server 拥有不同的体系结构,可以说是两个不同的产品.SQL Azure不完全支持或者尚不支持SQL Server的某些功能,这使得我们不能 ...

  10. SQL集合运算

    注:UserInfo一共29条记录 select * from UserInfo union --并集(29条记录)(相同的只出现一次) select * from UserInfo select * ...