表单

诸如<input><textarea><option>的表单组件与其它原生(native)组件不同,因为它们可以通过用户交互而被改变。这些组件提供的接口使得管理表单对用户交互的响应更加容易。

传统表单事件

传统表单的提交

  1. <form action='https://www.baidu.com' method='GET'>
  2. //action表单提交的地址
  3. //method表单提交的方式(GET比较小的数据提交,POST比较保密的提交)
  4. <input type="text" name="hello" placeholder="输入内容">
  5. <button>提交</button>
  6. //button作为提交按钮使用
  7. </form>

表单的事件

  • onSubimit(表单提交)
  • onChange(域的内容改变)
  • onInput(输入框内容的改变)
  • onBlur(失去焦点)//焦点事件
  • onFocus(获得焦点)//焦点事件inputtype属性
描述
button定义可点击按钮(多数情况下,用于通过 JavaScript 启动脚本)
checkbox定义复选框
file定义输入字段和 “浏览”按钮,供文件上传
hidden定义隐藏的输入字段
image定义图像形式的提交按钮
password定义密码字段。该字段中的字符被掩码
radio定义单选按钮
reset定义重置按钮。重置按钮会清除表单中的所有数据
submit定义提交按钮。提交按钮会把表单数据发送到服务器
text定义单行的输入字段,用户可在其中输入文本。默认宽度为 20 个字符
email定义邮箱

表单重置

  1. import React from 'react'
  2. class App extends React.Component {
  3. handleSubmit(e){
  4. e.preventDefault()
  5. //preventDefault 阻止跳转方法
  6. document.getElementById('form').reset()
  7. }
  8. render() {
  9. return (
  10. <div className="app">
  11. <form action='https://www.baidu.com' method='GET' id='form' onSubmit={this.handleSubmit.bind(this)}>
  12. <input type="text" name="hello" placeholder="输入内容" />
  13. <button>提交</button>
  14. <button type='reset'>重置</button>
  15. //重置按钮
  16. </form>
  17. </div>
  18. )
  19. }
  20. }
  21. export default App

小贴士reset()方法可把表单中的元素重置为它们的默认值

受控组件

非受控组件

  1. import React from 'react'
  2. class App extends React.Component {
  3. render() {
  4. return (
  5. <div className="app">
  6. <input type="text" placeholder="输入内容" value='123' />
  7. </form>
  8. </div>
  9. )
  10. }
  11. }
  12. export default App

一个没有value属性的<input>就是一个非受控组件。通过渲染的元素,任意的用户输入都会被立即反映出来。非受控的<input>只能通过OnChange函数来向上层通知自己被用户输入的更改。

可以用ref来拿到 输入的 value 值

  1. <input ref={value => this.username = value} />
  2. //this.username.value 拿到输入的值

注意:使用value代替defaultValue,会发现输入框的值无法改变

受控组件

表单的value值收到state的控制

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.handleChange = this.handleChange.bind(this)
  6. this.state = {
  7. input:''
  8. }
  9. }
  10. handleSubmit(e){
  11. e.preventDefault()
  12. let {input} = this.state
  13. }
  14. handleChange(e){
  15. this.setState({
  16. input:e.target.value
  17. //触发事件目标对象的value
  18. })
  19. }
  20. render() {
  21. return (
  22. <div className="app">
  23. <form onSubmit={this.handleSubmit.bind(this)}>
  24. <input value={this.state.input} onChange={this.handleChange} />
  25. <button>提交</button>
  26. </form>
  27. </div>
  28. )
  29. }
  30. }
  31. export default App

表单的selecttextarea输入

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. textarea:'',
  7. fruits:'banana'
  8. }
  9. }
  10. handleSubmit(e){
  11. e.preventDefault()
  12. let {textarea,fruits} = this.state
  13. console.log(textarea,fruits)
  14. }
  15. render() {
  16. return (
  17. <div className="app">
  18. <form onSubmit={this.handleSubmit.bind(this)}>
  19. <textarea cols="30" rows="10" value={this.state.textarea} onChange={e => this.setState({textarea:e.target.value})}></textarea><br/>
  20. <select value={this.state.fruits} onChange={e => this.setState({fruits:e.target.value})}>
  21. <option value="apple">苹果</option>
  22. <option value="orange">橘子</option>
  23. <option value="banana">香蕉</option>
  24. //默认值通过state控制,使用selected会被警告
  25. </select><br/>
  26. <button type='submit'>提交</button>
  27. </form>
  28. </div>
  29. )
  30. }
  31. }
  32. export default App

表单的radio输入

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. sex:'male'
  7. }
  8. }
  9. handleSubmit(e){
  10. e.preventDefault()
  11. let obj = this.state
  12. console.log(obj)
  13. }
  14. handleChange(e){
  15. this.setState({
  16. input:e.target.value
  17. })
  18. }
  19. render() {
  20. return (
  21. <div className="app">
  22. <form onSubmit={this.handleSubmit.bind(this)}>
  23. 男<input type="radio" name='sex' value='male' onChange={e => this.setState({sex:e.target.value})}/>
  24. 女<input type="radio" name='sex' value='female' onChange={e => this.setState({sex:e.target.value})}/><br/>
  25. <button type='submit'>提交</button>
  26. </form>
  27. </div>
  28. )
  29. }
  30. }
  31. export default App

表单的radio通过受控组件来控制checked的状态改变来修改,这种方法比较麻烦,所以我们用 非受控组件 来写表单的radio事件

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. sex:'male'
  7. }
  8. }
  9. handleSubmit(e){
  10. e.preventDefault()
  11. let obj = this.state
  12. console.log(obj)
  13. }
  14. handleChange(e){
  15. this.setState({
  16. input:e.target.value
  17. })
  18. }
  19. render() {
  20. return (
  21. <div className="app">
  22. <form onSubmit={this.handleSubmit.bind(this)}>
  23. 男<input type="radio" name='sex' value='male' checked={this.state.sex === 'male' ? true : false} onChange={e => this.setState({sex:e.target.value})}/>
  24. 女<input type="radio" name='sex' value='female' checked={this.state.sex === 'female' ? true : false} onChange={e => this.setState({sex:e.target.value})}/><br/>
  25. <button type='submit'>提交</button>
  26. </form>
  27. </div>
  28. )
  29. }
  30. }
  31. export default App

表单的checnkbox输入

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. agree:true
  7. }
  8. }
  9. handleSubmit(e){
  10. e.preventDefault()
  11. let obj = this.state
  12. console.log(obj)
  13. }
  14. handleChange(e){
  15. this.setState({
  16. input:e.target.value
  17. })
  18. }
  19. render() {
  20. return (
  21. <div className="app">
  22. <form onSubmit={this.handleSubmit.bind(this)}>
  23. 我已阅读并同意<input type="checkbox" value='agree' onChange={e =>this.setState({agree:!this.state.agree})}/><br/>
  24. <button type='submit'>提交</button>
  25. </form>
  26. </div>
  27. )
  28. }
  29. }
  30. export default App

checnkbox的多选

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.handleCheck = this.handleCheck.bind(this)
  6. this.state = {
  7. hobby:[]
  8. }
  9. }
  10. handleSubmit(e){
  11. e.preventDefault()
  12. let obj = this.state
  13. console.log(obj)
  14. }
  15. handleChange(e){
  16. this.setState({
  17. input:e.target.value
  18. })
  19. }
  20. handleCheck(e){
  21. let hobby = this.state.hobby
  22. let value = e.target.value
  23. let index = hobby.indexOf(value)
  24. console.log(index)
  25. if(index === -1){
  26. hobby.push(value)
  27. }else{
  28. hobby.splice(index,1)
  29. }
  30. this.setState({hobby})
  31. }
  32. render() {
  33. return (
  34. <div className="app">
  35. <form onSubmit={this.handleSubmit.bind(this)}>
  36. 兴趣爱好:<br/>
  37. 篮球<input type="checkbox" value='basketball' onChange={this.handleCheck}/><br/>
  38. 足球<input type="checkbox" value='football' onChange={this.handleCheck}/><br/>
  39. 排球<input type="checkbox" value='paiqiu' onChange={this.handleCheck}/><br/>
  40. 台球<input type="checkbox" value='taiqiu' onChange={this.handleCheck}/><br/>
  41. <button type='submit'>提交</button>
  42. </form>
  43. </div>
  44. )
  45. }
  46. }
  47. export default App

表单的重置:通过设置state为空来重置表单

  1. import React from 'react'
  2. class App extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. input:''
  7. }
  8. }
  9. handleSubmit(e){
  10. e.preventDefault()
  11. let obj = this.state
  12. console.log(obj)
  13. }
  14. handleReset(){
  15. this.setState({
  16. input:''
  17. })
  18. }
  19. render() {
  20. return (
  21. <div className="app">
  22. <form onSubmit={this.handleSubmit.bind(this)} onReset={this.handleReset.bind(this)}>
  23. <input type="text" value={this.state.input} onChange={e => this.setState({input:e.target.value})} />
  24. <button type='submit'>提交</button>
  25. <button type='reset'>重置</button>
  26. </form>
  27. </div>
  28. )
  29. }
  30. }
  31. export default App

处理多个输入

  1. import React from 'react'
  2. class Input extends React.Component {
  3. constructor(){
  4. super()
  5. this.state = {
  6. textarea:'',
  7. fruits:'banana'
  8. }
  9. }
  10. handleChange(type,e){
  11. this.setState({
  12. [type]:e.target.value
  13. })
  14. }
  15. render() {
  16. return (
  17. <div>
  18. <textarea
  19. cols="30"
  20. rows="10"
  21. value={this.state.textarea}
  22. onChange={this.handleChange.bind(this,'textarea')}>
  23. </textarea><br/>
  24. <select value={this.state.fruits} onChange={this.handleChange.bind(this,'fruits')}>
  25. <option value="apple">苹果</option>
  26. <option value="orange">橘子</option>
  27. <option value="banana">香蕉</option>
  28. </select><br/>
  29. <button onClick={() => console.log(this.state)}>提交</button>
  30. </div>
  31. )
  32. }
  33. }
  34. export default Input

注意:传入的type参数与对应state的名字

混合组件的优点

  • 支持传入默认值;
  • 可控:组件外部修改props可改变input组件的真实值及显示值;
  • 非可控:输入框中输入值,可同时改变input组件的真实值及显示值。