React之表单
第一部分:表单基础
在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之表单的更多相关文章
- 【09】react 之 表单组件
不太清楚有多少初学React的同学和博主当时一样,在看完React的生命周期.数据流之后觉得已经上手了,甩开文档啪啪啪的开始敲了起来.结果...居然被一个input标签给教做人了. 故事是这样的:首先 ...
- 前端笔记之React(二)组件内部State&React实战&表单元素的受控
一.组件内部的State 1.1 state state叫状态,是每一个类式组件都有的属性,但函数式组件,没有state. state是一个对象,什么值都可以定义. 在任何类式组件的构造函数中,可以用 ...
- react Input 表单
input react 表单 input 密码框在谷歌浏览器下 会有黄色填充 官网的不太用,这个比较好用 type="password" autoComplete=" ...
- react.js 表单验证-登录框
import React,{ Component } from 'react'; import style from 'cms.css'; /** * 路由路径 登录成功后页面跳转到index * ...
- react dva 表单校验
import React,{ Component } from 'react'; import { connect } from 'dva'; import { WhiteSpace,NavBar , ...
- react 表单
import React ,{PropTypes}from 'react'; import { render } from 'react-dom'; const styles={ mb10:{ mar ...
- react引用antd的form表单
引用form是第三方插件ant插件,官网网址:https://ant.design/.用到的antd的版本是@2.0.1.form(https://ant.design/components/form ...
- 群里分享的react的收藏一下!今日周末,改了个表单验证然后无所事事了!
今日周末,改了个表单验证然后无所事事了,然后把昨天群里分享的react的收藏一下尽管现在还在研究angular和nodeJs毕竟刚刚开始用有点不熟...没准以后会研究一下react毕竟看着下面这张图还 ...
- React表单元素的使用
一. <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF ...
随机推荐
- (最小生成树)Eddy's picture -- hdu -- 1162
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1162 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- java并发编程实战:第六章----任务执行
任务:通常是一些抽象的且离散的工作单元.大多数并发应用程序都是围绕"任务执行"来构造的,把程序的工作分给多个任务,可以简化程序的组织结构便于维护 一.在线程中执行任务 任务的独立性 ...
- Ubuntu的常识使用了解4
寻找文件的「名称」 在Linux系统当中,文件的数量非常非常的多, 需要使用查找工具来高效查找指定文件位置:
- 让FIREDAC记录数据库的异常日志
默认FIREDAC不会记录数据库的异常. 比如典型的,提交的时候,非空字段没有给值. 某些人还以为FIREDAC不能捕获数据库的异常,其实FIREDAC是可以捕获并处理数据库的异常事件的. 方法异常简 ...
- Python学习-11.Python中的类定义
Python是一门面向对象语言,那么作为面向对象的特征——类也是有的.值得注意的是Python中一切皆对象,并不像C#中为了性能考虑,int这些在Python中也是对象.(C#中int是结构体) 如何 ...
- [C#学习笔记]分部类和分部方法
知识在于积累. 前言 好久没写博客了,因为在看<CLR via C#>的时候,竟然卡在了分部方法这一小节几天没下去.今天重新认真阅读,有些感悟,所以在此记录. 然后. 每天早晨第一句,&l ...
- Devexpress Winform初学笔记
作为一个软件开发人员来说,得有自己的博客,可以用来ZB,哈哈!玩笑话..... 写博客并不仅仅是用来ZB的,他可以用来记录你在技术道路上探索遇到的坎,当然也有提高逼格的次然因素啦!小弟刚入博客园不久, ...
- update sharepoint 2013 cu error
1. 安装过程合理: A. 可以同时在管理中心.两台前端.搜索服务器上安装重新发布的SP1补丁包(所提供的链接) B. 等待所有SP1补丁包安装完成,依次在管理中心.两台前端.搜索服务器上运行配置向导 ...
- Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]
原文链接:http://www.cnblogs.com/sammyliu/p/4843812.html?utm_source=tuicool&utm_medium=referral 1 Poo ...
- Sublime写作
下载 Sublime Text 快捷键(MAC环境) sublime text 批量删除空白行 Sublime text3!行首,行尾,批量编辑!