表单

诸如<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的名字

混合组件的优点

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