React 受控组件中不同域数据的获取方式

受控组件

1、什么是受控组件

  • 受控组件通常指的是表单,因为HTML中的表单是可输入的,也就是有自己的可变状态
  • React中可变状态通常保存在state 中,并且只能通过setState()方法来修改
  • React 将 state与表单的 value值绑定到一起,给表单元素绑定change事件,将表单元素的值设置为state的值,接收表单值变化

2、核心步骤

第一步:在state中设置数据

 state = {
    txt:''
  }

第二步:表单域中将 state中的数据与value绑定

 <input 
 	type="text" 
 	value={this.state.txt} 
 </input>

此时,value与txt 绑定,所以文本框中默认写入

第三步:给表单绑定onChange事件

 <input 
 	type="text" 
 	value={this.state.txt} 
 	onChange={this.handleChange}>
 </input>

第四步:事件函数中调用 setState 将数据进行保存

 handleChange = e=>{
    this.setState({
      txt:e.target.value
    })
  }

参数:e是事件对象
e.target.value保存了input中的value值
React 受控组件中不同域数据的获取方式

3、不同域数据的获取方式

  • 每个域都要将 value 和 state 中对应的属性绑定
  • 每个域都要绑定 onChange 事件

举例: 点击登录按钮,将文本框中的值输出到终端

给input、select、textarea表单域分别绑定onChange事件

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
  state = {
    txt: '1234',
    city: '北京',
    desc: '好好学习,天天向上'
  }
  handleChange = e => {
    this.setState({
      txt: e.target.value
    })
  }

  handleCity = e => {
    this.setState({
      city: e.target.value
    })
  }

  handleDesc = e => {
    this.setState({
      desc: e.target.value
    })
  }
  submit = () => {
    console.log(this.state)
  }
  
  render () {
    return (
      <div>
        账号: <input type="text" value={this.txt} onChange={this.handleChange} /><br />
        城市: <select value={this.city} onChange={this.handleCity}>
                <option value="bj">北京</option>
                <option value="sh">上海</option>
                <option value="sz">深圳</option>
              </select><br />
        描述: <textarea value={this.desc} onChange={this.handleDesc}></textarea><br />
        <button onClick={this.submit}>登录</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

React 受控组件中不同域数据的获取方式
当我们输入数据之后,根据每个域的属性绑定,点击登录按钮,终端会显示出我们输入的数据

React 受控组件中不同域数据的获取方式

4、合并处理

核心:e.target

  • e.target.value : 保存了标签中的value值
  • e.target.name:保存了标签中的name值

每个域中name属性绑定 state 中对应的属性, onChange指定一个函数统一处理

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
  state = {
    account: '',
    city: '',
    desc: ''
  }

  handleForm = e => {
    const {name, value} = e.target
    this.setState({
      [name]: value 
    })
  }

  submit = () => {
    console.log(this.state)
  }

  render () {
    return (
      <div>
        账号: <input name="account" type="text" value={this.account} onChange={this.handleForm} /><br />
        城市: <select name="city" value={this.city} onChange={this.handleForm}>
                <option value="bj">北京</option>
                <option value="sh">上海</option>
                <option value="sz">深圳</option>
              </select><br />
        描述: <textarea name="desc" value={this.desc} onChange={this.handleForm}></textarea><br />
        <button onClick={this.submit}>登录</button>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('root'))      

React 受控组件中不同域数据的获取方式

案例:评论列表

  • 渲染评论列表,利用列表渲染方法
  • 没有列表数据时渲染:暂无评论,利用条件渲染方法
  • 获取评论信息,包括评论人和评论内容,利用受控组件
  • 发表评论,更新评论列表,使用setState()方法

1、渲染评论列表

  • 在state中初始化评论列表数据
state={
   //初始化状态
   comment:[
     {id:1,name:'小王',content:'你好机智'},
     {id:2,name:'小赵',content:'你好笨'},
     {id:3,name:'小刘',content:'你好完美'}
   ]
 }
  • 使用数组的map方法遍历state中的列表数据
  • 给每个被遍历的li元素添加key属性,可以避免评论信息一样
<ul>
       {
         this.state.comment.map(item=>(
           <li key = {item.id}>
              <h3>评论人:{item.name}</h3>
              <p>评论内容:{item.content}</p>
           </li>
         ))}
     </ul>

2、渲染暂无评论

判断列表长度是否为0,如果长度为0,便渲染暂无评论

 //渲染评论列表
  renderList(){
    return   this.state.comment.length === 0?
      (<div className='no-content'> 暂无评论,快去评论吧 </div>)
      :( <ul>
        {this.state.comment.map(item=>(
            <li key = {item.id}>
               <h3>评论人:{item.name}</h3>
               <p>评论内容:{item.content}</p>
            </li>
          ))}
      </ul>)
  }

效果:
React 受控组件中不同域数据的获取方式
React 受控组件中不同域数据的获取方式
3、获取表单信息

准备状态分别控制两个表单元素,并通过创建一个函数处理表单元素值,使onChange指定这个函数统一处理,并且name属性需绑定 state 中对应的属性

//评论人
userName:'',    
//评论信息
userContent:''
handleForm = (e) =>{
    const {name,value} = e.target
    this.setState({
      [name]:value
    })
  }

4、发表评论

给按钮绑定单击事件,在事件处理程序中,通过state获取评论信息,并将评论信息添加到state中,并调用setState()方法来更新state

 //发表评论
  addComment = ()=>{
    const {comment,userName,userContent} = this.state
    console.log(userName,userContent);
    
    const newComment = [{
      id:Math.random(),
      name:userName,
      content:userContent
    },...comment]
    console.log(newComment)
    this.setState({
      comment:newComment
    })
  }

效果:发出评论之后,可以将评论置顶在第一条
React 受控组件中不同域数据的获取方式
完整代码:

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
  state={
    //初始化状态
    comment:[
      {id:1,name:'小王',content:'你好机智'},
      {id:2,name:'小赵',content:'你好笨'},
      {id:3,name:'小刘',content:'你好完美'}
    ],
    //评论人
    userName:'',

    //评论信息
    userContent:''
  }
  //渲染评论列表
  renderList(){
    return   this.state.comment.length === 0?
      (<div className='no-content'> 暂无评论,快去评论吧 </div>)
      :( <ul>
        {this.state.comment.map(item=>(
            <li key = {item.id}>
               <h3>评论人:{item.name}</h3>
               <p>评论内容:{item.content}</p>
            </li>
          ))}
      </ul>)
  }
  //处理表单元素值
  handleForm = (e) =>{
    const {name,value} = e.target
    this.setState({
      [name]:value
    })
  }
  //发表评论
  addComment = ()=>{
    const {comment,userName,userContent} = this.state
    console.log(userName,userContent);
     //非空校验
      if(userName.trim()===''||userContent.trim()===''){
   		   alert('请输入评论人和评论内容')
   		   return
   }
   
    const newComment = [{
      id:Math.random(),
      name:userName,
      content:userContent
    },...comment]
    console.log(newComment)
    this.setState({
      comment:newComment,
      //在点击完评论之后清空文本框
      userName:'',
      userContent:''
    })
  }
  render () {
    const {userName,userContent} = this.state
    return (
      <div className='app'>
        <div>
        <input className='user' type='text' placeholder="请输入评论人" value={userName} name='userName' onChange={this.handleForm}/>
        <br/>
        <textarea 
          className='content'
          cols='30'
          rows='10'
          placeholder="请输入评论内容"
          value={userContent}
          onChange={this.handleForm}
          name = "userContent"
          />
        <br/>
        <button onClick={this.addComment}>发表评论</button>
      </div>
      {this.renderList()}
    </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('root'))      
上一篇:JDK源码==》LinkedHashMap类学习


下一篇:设备树(三):资源解析【转】