[React]Day05—React 表单中受控组件与非受控组件

本文详细介绍了React中的受控组件和非受控组件。受控组件通过React的状态管理和onChange事件控制表单数据,而非受控组件则使用ref获取表单元素的值。此外,还展示了如何使用高阶函数简化受控组件的onChange处理,并对比了使用和不使用高阶函数的情况。
摘要由CSDN通过智能技术生成

Day05—React 表单中受控组件与非受控组件

一、受控组件

作者:LinDaiDai_霖呆呆
链接:https://juejin.cn/post/6858276396968951822

在HTML的表单元素中,它们通常自己维护一套state,并随着用户的输入自己进行UI上的更新,这种行为是不被我们程序所管控的。

而如果将React里的state属性和表单元素的值建立依赖关系,再通过onChange事件与setState()结合更新state属性,就能达到控制用户输入过程中表单发生的操作。

被React以这种方式控制取值的表单输入元素就叫做受控组件

比如 input 、select、checkbox 等都是受控组件

我们可以提前通过表单控件的value,初始化 state 来设置它们的初始值

class Controll extends React.Component{

  // 初始化 state
  state ={
    username:"",
    password:""
  }
 
  usernameChange=(e)=>{
    this.setState({username:e.target.value})
  }

  passwordChange=(e)=>{
    this.setState({password:e.target.value})
  }

  submit=(e)=>{
    e.preventDefault() //阻止表单自动提交
    const {username,password} = this.state
   
    alert(`用户名:${username},密码:${password}`)

  }
  render (){
    return ( 
      <form onSubmit={this.submit}>
          用户名:<input type="text" name="username"  onChange={this.usernameChange} />
          <br/><br/>
          密码:<input type="password" name="password"  onChange={this.passwordChange} />
          <br/><br/>
          <button type="submit">提交</button>
      </form>
    ) 
  }
}

ReactDOM.render(<Controll/>,document.getElementById('test'))
二、非受控组件

应用场景:

想要获取某个表单元素的值,而不关心它是如何改变的,使用 ref 就可以实现

file类型的表单控件它始终是一个非受控的组件,因为它的值只能由用户设置,而不是以编程方式设置。

class UnControll extends React.Component {
  constructor(props) {
    super(props);
    this.fileRef = React.createRef();
  }
  handleSubmit = (e) => {
    console.log('我们可以获得file的值为', this.fileRef.current.files);
    e.preventDefault();
  }
  render() {
    return (
      <form onSubmit={e => this.handleSubmit(e)}>
        <input type="file" ref={this.fileRef} />
        <input type="submit" value="提交" />
      </form>
    )
  }
}

ReactDOM.render(<UnControll />, document.getElementById('test'))
三、高阶函数
/**
* 满足以下任意条件的函数 称为 高阶函数 
 *  
 *  1. 函数的参数为一个函数
 *  2. 函数返回值为一个函数 
 * 
 */    
 
 /**
  * 函数柯里化
  * 
  * 通过函数调用继续返回函数的方式,实现多次接收参数,最后统一处理的编码形式
  * 
 */
 
  function sum(a){
    return (b)=>{
      return (c)=>{
        return a+b+c
      } 
    }
  }

  console.log(sum(1)(2)(3));
<script type="text/babel">
/* 注意 type:text/babel  否则浏览器不认识 VDOM */
  class Controll extends React.Component{

    // 初始化 state
    state ={
      username:"",
      password:""
    }
   
   //注意这里,返回一个匿名函数
    handleChange=(dataType)=>{ 
      return (e)=>{
        this.setState({[dataType]:e.target.value}) 
      }
    }

    submit=(e)=>{
      e.preventDefault() //阻止表单自动提交
      const {username,password} = this.state
     
      alert(`用户名:${username},密码:${password}`)

    }
    render (){
      return ( 
        <form onSubmit={this.submit}>
            用户名:<input type="text" name="username"  onChange={this.handleChange('username')} />
            <br/><br/>
            密码:<input type="password" name="password"  onChange={this.handleChange('password')} />
            <br/><br/>
            <button type="submit">提交</button>
        </form>
      ) 
    }
  }
 ReactDOM.render(<Controll/>,document.getElementById('test'))
四、不使用高阶函数
class Controll extends React.Component{

  // 初始化 state
  state ={
    username:"",
    password:""
  }
 
  handleChange=(dataType,e)=>{  
    this.setState({[dataType]:e.target.value})   
  }

  submit=(e)=>{
    e.preventDefault() //阻止表单自动提交
    const {username,password} = this.state
   
    alert(`用户名:${username},密码:${password}`)

  }
  render (){
    return ( 
      <form onSubmit={this.submit}>
          用户名:<input type="text" name="username"  onChange={e => this.handleChange('username',e)} />
          <br/><br/>
          密码:<input type="password" name="password"  onChange={e => this.handleChange('password',e)} />
          <br/><br/>
          <button type="submit">提交</button>
      </form>
    ) 
  }
} 

ReactDOM.render(<Controll/>,document.getElementById('test')) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值