首页 > 其他 > 详细

React组件 (三)

时间:2021-03-09 11:14:52      阅读:22      评论:0      收藏:0      [点我收藏+]

组件实例的三大属性 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"))

React组件 (三)

原文:https://www.cnblogs.com/jing428/p/14487229.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!