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 ...
随机推荐
- 移动端html5页面导航栏悬浮遮挡内容第一行解决办法
参考:https://zhidao.baidu.com/question/1608232105428062147.html 1.设置导航栏div属性position:fixed; .nav-fixed ...
- J-Link eclipse Plug-ins install
Quicklinks If you know what this is all about and you just need the update site details: name: GNU A ...
- Replication--如何使用快照来初始化化请求订阅
这是一篇针对新人的知识普及文章,老人慎入! 在快照发布和事务发布中,SQL Server需要使用快照来将数据库某一时间点的数据传递给订阅,快照使用BCP的机制. 首先我们需要查看和设置快照的生成目录, ...
- XML--使用XML来将字符串分隔成行数据
DECLARE @xml XML SET @xml=CAST(REPLACE('<ROOT><X>'+'AA,AB,AC,AD'+'</X></ROOT> ...
- Bug报告提交规范
首先声明,bug的测试规范应该在公司的正式文档建立.本建议非正式文档,有些内容可能不正确,有些内容可能需要继续商榷,甚至有些内容同公司规范有冲突.如果发现问题,直接忽略本文相应内容.本帖本意仅就工作中 ...
- kv数据库对比总结
集群型: hbase Cassandra scylladb redis类: redis + twemproxy codis 持久型: pika ssdb
- tar.gz 解压
tar -xzvf .tar.gz tar [-cxtzjvfpPN] 文件与目录 .... 参数: -c :建立一个压缩文件的参数指令(create 的意思): -x :解开一个压缩文件的参数指令! ...
- [JAVA]java复制文件的4种方式
尽管Java提供了一个可以处理文件的IO操作类. 但是没有一个复制文件的方法. 复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候. 然而有几种方法可以进行Java文件复制操作,下面列举出 ...
- Django博客项目思路整理
首先明确一点,我目前学习Django是为了做一个博客,那么以博客为目标进行实践的话,按照Django的MTV模型的顺序来思考的话,要考虑如下几个事情: (Models) 1.在博客里的各种数据模型: ...
- 对象初始化的完整过程(C#)
1.静态构造函数 在引入本文的主题之前,我们先来铺垫一下吧,看看静态构造函数的概念及用途. C#中允许创建无参数构造函数,该函数仅执行一次.它一般被用来初始化静态字段.CLR不能保证在某个特定时刻执行 ...