zoukankan      html  css  js  c++  java
  • React组件 (三)

    组件实例的三大属性 3 : refs

    (1)ref用于标识组件内部某个元素(组件内的标签可以定义ref属性来标识自己)

    (2)refs 是标识集合

    字符串形式的refs

    <input ref="input1"/>

    例子

    
    class Demo extends React.Component{ 
        getData = () => {
            console.log(this.refs.input1.value); 
        }
    
        getData1 = () => {
            console.log(this.refs.input2.value); 
        } 
        render(){
            return (
                <div>
                    <input type="text" placeholder="点击按钮提示数据" ref="input1"/> 
                    <button onClick={this.getData} ref="button">点击按钮</button>
                    <input type="text" placeholder="失去焦点提示数据" ref="input2" onBlur={this.getData1}/> 
                </div>
            )
        }
    }
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    回调形式的refs

    <input ref={(c)=>{this.input1 = c}}/>

    例子

    
    class Demo extends React.Component{ 
        getData = () => {
            console.log(this.input1.value); 
        } 
        getData1 = () => {
            console.log(this.input2.value); 
        } 
        render(){
            return (
                <div>
                    <input type="text" placeholder="点击按钮提示数据" ref={(currentNode) => {this.input1 = currentNode,console.log("3333")}}/> 
                    <button onClick={this.getData} ref="button">点击按钮</button>
                    <input type="text" placeholder="失去焦点提示数据" ref={c => this.input2 = c} onBlur={this.getData1}/> 
                </div>
            )
        }
    }
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    回调ref中调用次数的问题

    关于回调 refs 的说明

    如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。

    
    class Demo extends React.Component{  
    state = {
      isHot:true
    } 
    getData = () => {
      console.log(this.input1.value); 
    } 
    changeWether = () => {
      this.setState({
          isHot:!this.state.isHot
      })
    } 
    render(){
      const {isHot} = this.state 
      return (
          <div>
              <h1>今天天气{isHot ? '炎热':'凉爽'}</h1>
              <input type="text" placeholder="点击按钮提示数据" ref={(currentNode) => {this.input1 = currentNode,console.log("@1222",currentNode)}}/> 
              <button onClick={this.getData} ref="button">点击按钮</button>
              <button onClick={this.changeWether}>点击切换天气</button>
          </div>
      )
    }
    }
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    react提供的解决办法

    
    saveInput = (currentNode) => {
        this.input1 = currentNode;
        console.log("@1222",currentNode)
    }
    
    <input type="text" ref={this.saveInput}/>
    
    

    createRef创建ref容器

    
    myRef = React.createRef() 
    <input ref={this.myRef}/>
    
    

    例子

    
    class Demo extends React.Component{  
        /**
         * React.createRef 调用后可以返回一个容器,该容器可以存储被ref所标识的节点
         * 该容器是“专人专用的”
         */ 
        myRef = React.createRef(); 
        myRef2 = React.createRef(); 
        getData = () => {
            console.log(this.myRef.current.value); 
        } 
        getData1 = () => {
            console.log(this.myRef2.current.value); 
        } 
        render(){
            return (
                <div>
                    <input type="text" placeholder="点击按钮提示数据" ref={this.myRef}/> 
                    <button onClick={this.getData} ref="button">点击按钮</button>
                    <input type="text" placeholder="失去焦点提示数据" ref={this.myRef2} onBlur={this.getData1}/> 
                </div>
            )
        }
    }
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    事件处理

    1)通过onXxx属性指定事件处理函数(注意大小写)

    a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 ————为了更好的兼容性

    b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ———— 为了高效

    2)通过event.target得到发生事件的DOM元素对象 ———— 勿过度使用 Refs

    
    class Demo extends React.Component{   
       myRef = React.createRef(); 
       myRef2 = React.createRef(); 
       getData = () => {
           console.log(this.myRef.current.value); 
       } 
       getData1 = () => {
           console.log(event.target.value);  // 通过event.target得到发生事件的DOM元素对象
       } 
       render(){
           return (
               <div>
                   <input type="text" placeholder="点击按钮提示数据" ref={this.myRef}/> 
                   <button onClick={this.getData} ref="button">点击按钮</button>
                   <input type="text" placeholder="失去焦点提示数据" ref={this.myRef2} onBlur={this.getData1}/> 
               </div>
           )
       }
    }
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    收集表单数据

    需求

    定义一个包含表单的组件

    输入用户名密码后, 点击登录提示输入信息

    非受控组件

    表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用 ref从DOM获取表单值)

    
    class LoginForm extends React.Component{   
        myRef = React.createRef(); 
        myRef2 = React.createRef(); 
        getData = (event) => {
            event.preventDefault(); // 阻止表单提交
            console.log(`用户名是:${this.myRef.current.value};密码是:${this.myRef2.current.value}`); 
        } 
         
        render(){
            return (
                <form onSubmit={this.getData}>
                    用户名是:<input type="text" placeholder="请输入用户名" ref={this.myRef} name="username"/><br/>
                    密码:<input type="password" placeholder="请输入密码" ref={this.myRef2} name="password"/><br/>
                    <button>登录</button> 
                </form>
            )
        }
    }
    ReactDOM.render(<LoginForm />,document.getElementById("test"))
    

    受控组件

    在HTML中,标签<input><textarea><select>的值的改变通常是根据用户输入进行更新。在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。

    class LoginForm extends React.Component{  
        state = {
            username:"",
            password:""
        }
    
        getData = (event) => {
            event.preventDefault(); // 阻止表单提交
            console.log(`用户名是:${this.state.username};密码是:${this.state.password}`); 
        } 
    
        
        getUserName = (event) => {
            this.setState({
                username:event.target.value
            })
        }
    
        getPassword = (event) => {
            this.setState({
                password:event.target.value
            })
        }
         
        render(){
            return (
                <form onSubmit={this.getData}>
                    用户名是:<input type="text" placeholder="请输入用户名" name="username" onChange={this.getUserName}/><br/>
                    密码:<input type="password" placeholder="请输入密码" name="password" onChange={this.getPassword}/><br/>
                    <button>登录</button> 
                </form>
            )
        }
    }
    ReactDOM.render(<LoginForm />,document.getElementById("test"))
    

    高阶函数-柯里化

    高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。

    • 1.若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。

    • 2.若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。

    • 常见的高阶函数有:Promise、setTimeout、arr.map()等等

    函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。

    
    function sum(a){
      return(b)=>{
        return (c)=>{
          return a+b+c
        }
      }
    }
    
    
    
    
    class LoginForm extends React.Component{  
      state = {
          username:"",
          password:""
      }
    
      getData = (event) => {
          event.preventDefault(); // 阻止表单提交
          console.log(`用户名是:${this.state.username};密码是:${this.state.password}`); 
      }  
     
      saveFormData = (dataType) => { 
          return (event) => {
              this.setState({
                  [dataType]:event.target.value
              })
          }
      }
       
      render(){
          return (
              <form onSubmit={this.getData}>
                  用户名是:<input type="text" placeholder="请输入用户名" name="username" onChange={this.saveFormData('username')}/><br/>
                  密码:<input type="password" placeholder="请输入密码" name="password" onChange={this.saveFormData('password')}/><br/>
                  <button>登录</button> 
              </form>
          )
      }
    }
    ReactDOM.render(<LoginForm />,document.getElementById("test"))  
    

    不用柯里化的写法

    
    saveFormData = (dataType,event) => {  
        this.setState({
            [dataType]:event.target.value
        })
        
    }
     
    render(){
        return (
            <form onSubmit={this.getData}>
                用户名是:<input type="text" placeholder="请输入用户名" name="username" onChange={(event) => {this.saveFormData('username',event)}}/><br/>
                密码:<input type="password" placeholder="请输入密码" name="password" onChange={(event) => {this.saveFormData('password',event)}}/><br/>
                <button>登录</button> 
            </form>
        )
    }
    
  • 相关阅读:
    如何写README.md
    (2020-03-29)--------paper list
    ROS(八)----示例
    ROS(七)----动态参数
    ROS(六)----参数
    ROS(四)---自定义消息.msg
    ROS(三)-----节点的定义
    ROS(二)-------RoboWare Studio
    ROS(一)-----ros 安装
    pytorch(4)----nn.Module、nn.functional、nn.Sequential、nn.optim
  • 原文地址:https://www.cnblogs.com/jing428/p/14487229.html
Copyright © 2011-2022 走看看