React(8)-组件ref引用

目录

1.组件form

受控组件及其特点

非受控组件及其特点

模拟:简单受控组件表单

        input两个方向绑定数据:

模拟:复杂(真实)受控组件表单(form里面有多种数据输入)

注意:handleChange1~5 中代码重复率高。

降低代码重复写法降低代码重复写法

模拟:非受控组件

受控组件形式自动时钟

非受控组件形式自动时钟

2.ref-函数类型实现

3.createRef实现

createRef实现自动化时钟

2.业务场景(登录)=>ref模拟form表单收集

三种非受控表单解决方式

方式一:ref="key"  原理:this.refs={} => this.refs={key:真实DOM}

方式二:ref={e=>this.key=e} =>直接赋值this.key=真实DOM

方式三:直接调用react提供的方法createRef();this.key=React.createRef()

事件绑定受控表单方式

3.业务衍生场景=>按钮触发事件

4.业务衍生场景=>表单自动获取焦点


1.组件form

受控组件及其特点

组件受状态和属性变化控制,称为受控组件。

特点:数据驱动,组件不直接操作DOM,而是由ReactDOM自动同步

非受控组件及其特点

组件不受状态和属性变化控制,称为非受控组件。

特点:可以直接操作DOM,类似于传统的html表单操作,通过ref获取真实DOM。

模拟:简单受控组件表单

(数据传递) =>数据源state+属性绑定value+事件监听onChange

class App extends React.Component{

        state = {name:"",age:18}

        handleClick = () ={

                console.log("form data:",this.state)

        }

        handleChange = (e) ={

                console.log(e.target.value) //获取到input输入内容

                this.setState({

                        name:e.target.value      

                })

        }

        input两个方向绑定数据:

        1.通过value,同步state=>input (属性绑定)

        2.通过onChange,同步input输入输入内容=>state  (事件绑定)

        render(){

                return(

                        <div>

                                name:

                                //受控组件收集表单

                                <input type:"text" value = {this.state.name} // input属性绑定

                                        onChange={this.handleCHange}> //input事件绑定

                                <button onClick={this.handleClick}>commit 提交</button>

                        </div>

                )

        }

}

ReactDOM.render(<App />,document.getElementById("app"))

模拟:复杂(真实)受控组件表单(form里面有多种数据输入)

class App extends React.Component{

        state = {

                name:"user",

                age:18,

                single:false,

                desc:"intoduction",

                hobby:"playing"

        }

        handleSubmit=()={

                //获取收集表单数据

                console.log("form data:",this.state)

                //提交数据

                //阻止默认行为

                e.preventDefault()

        }

        handleChange1 = (e) ={

                this.setState({

                        name:e.target.value

                })

        }

        handleChange2 = (e) ={

                this.setState({

                        age:e.target.value

                })

        }

        handleChange3 = (e) ={

                console.log(e.target.checked) //点击,在true和false之间来回切换

                //将表单中内容同步到数据中

                this.setState({

                        single:e.target.checked

                })

        }

        handleChange4 = (e) ={

                this.setState({

                        desc.target.value

                })

        }

        handleChange5 = (e) ={

                this.setState({

                        hobby:e.target.value

                })

        }

        render(){

                return(

                        <form onSubmit = {this.handleSubmit}>

                                name:

                                <input type:"text" value = {this.state.name} // input属性绑定

                                        onChange={this.handleChange1} /> //input事件绑定

                                age:

                                <input type:"number" value = {this.state.age

                                        onChange={this.handleChange2} /> 

                                single:

                                <input type:"checkbox" value = {this.state.single

                                        onChange={this.handleChange3} /> 

                                desc:

                                <textarea value = {this.state.desc}

                                        onChange={this.handleChange4}/>

                                hobby:

                                <select name:"" value={this.state.hobby}

                                        onChange={this.handleChange5}>

                                        <option value:"eatting">吃</option>

                                        <option value:"palying">玩</option>

                                        <option value:"sleeping">睡</option>

                                </select>

                                <input type="submit" value="commit" />

                        </form>

                )

        }

}

ReactDOM.render(<App />,document.getElementById("app"))

注意:handleChange1~5 中代码重复率高。

this.setState({key:value}),key动态,value:r.target.value,注意:e.target.checked不同

降低代码重复写法降低代码重复写法

class App extends React.Component{

        state = {

                name:"user",

                age:18,

                single:false,

                desc:"intoduction",

                hobby:"playing"

        }

        handleSubmit=()={

                //获取收集表单数据

                console.log("form data:",this.state)

                //提交数据

                //阻止默认行为

                e.preventDefault()

        }

        handleChange = (e) ={

                console.dir(e.target)

                let target = e.target

                let key = target.name

                //注意:checkedbox情况不同value = target.checked,追加判断

                let type = target.type

                let value = type==checkedbox?target.checked:target.value

                this.setState({

                       [key]:value //动态追加key

                })

        }

   

        render(){

                return(

                        <form onSubmit = {this.handleSubmit}>

                                name:

                                <input type:"text" name="name" 

                                        value = {this.state.name}

                                        onChange={this.handleChange} /> 

                                age:

                                <input type:"number" name="age" 

                                        value = {this.state.age

                                        onChange={this.handleChange} /> 

                                single:

                                <input type:"checkbox" name="single" 

                                        value = {this.state.single

                                        onChange={this.handleChange} /> 

                                desc:

                                <textarea name="desc" 

                                        value = {this.state.desc}

                                        onChange={this.handleChange}/>

                                hobby:

                                <select name:"hobby" value={this.state.hobby}

                                        onChange={this.handleChange}>

                                        <option value:"eatting">吃</option>

                                        <option value:"palying">玩</option>

                                        <option value:"sleeping">睡</option>

                                </select>

                                <input type="submit" value="commit" />

                        </form>

                )

        }

}

ReactDOM.render(<App />,document.getElementById("app"))

模拟:非受控组件

受控组件形式自动时钟

class Clock extends React.Components{

        state = {time:new Date().toLocalTimeString()}

        render(){

                return(

                        <div>

                                <h2>{this.state.time}</h2>

                        </div>

                )

        }

        componentDidMount(){ //第一次挂载完毕生命周期的钩子函数自动执行

                setInterval(()=>{

                        this.setState({

                                time:new Date().toLocalTimeString()

                        })

                },1000)

        }

}

ReactDOM.render(<Clock />,document.getElementById("app"))

非受控组件形式自动时钟

1.真实DOM容器ref-string类型实现

组件实例属性:this.ref = {},这个对象容器用来存储真实DOM的引用

class Clock extends React.Component{

        render(){

                return(

                        <div>

                                2.将真实DOM放在this.ref容器中

通过creatElement创建虚拟DOM,新增ref属性

通过ReactDOM.render同步渲染虚拟DOM=>真实DOM=>判断是否有ref属性

==>有ref:将ref属性对应的虚拟DOM转化成真实DOM=>放在this.ref={}容器中

[ 将ref属性对应的值作为key,将真实DOM作为value ]

                                <h2 ref="timeRef">{new Date().toLocalTimeString()}</h2>

                                //ref容器中存放:{timeRef:真实DOM<h2>}

                        </div>

                )

        }

        componentDidMount(){ //已经渲染完毕,可以拿到真实DOM

                console.log(this.refs

                setInterval(()=>{

                        3.this.ref中获取操作真实DOM=>给<h2>重新赋值

                        this.refs.timeRef.innerHTML = new Date().toLocaleTimeString()

                },1000)

        }

}

ReactDOM.render(<Clock />,document.getElementById("app"))

组件实例.refs = {key:真实DOM} ; key是ref属性对应的值

组件实例直接挂载key,组件实例.key=真实DOM => 自动化时钟

2.ref-函数类型实现

class Clock extends React.Component{

        render(){

                return(

                         <div>

                                2.将真实DOM放在this.ref容器中

通过creatElement创建虚拟DOM,新增ref属性

通过ReactDOM.render同步渲染虚拟DOM=>真实DOM=>判断是否有ref属性

==>有ref:ref属性对应的值是否是一个函数

==>是函数,直接执行这个函数,并将真实DOM作为参数传递。[组件实例.key=真实DOM]

                                <h2 ref = {e=>this.timeRef=e}>{new Dare().oLocaleTimeString()}</h2>

                                <h2 ref = {(element)=>{this.timeRef2=element}}>

                                        {new Date().toLocalTimeString()}

                        </div>       

                )

        }

        //组建挂载完毕:组件第一次渲染完毕执行=>虚拟DOM已经完全转化为真实DOM

        compomentDidMount(){

                console.loh(this)//组件实例

                console.loh(this.ref)//组件ref容器

                setInterval(()=>{

                        //this.key = 真实DOM{对应此处的<h2>标签}

                        this.refs.timeRef.innerHTML = new Date().toLoacleTimeString();

                        this.refs.timeRef.innerHTML = new Date().toLoacleTimeString();

                })

        }

}

ReactDOM.render(<Clock />,document.getElementById("app"))

3.createRef实现

React中creatRef源码:

//a immutable object(不可改变的对象) with single mutable value

function creatRef(){

        var refObject={

                current:null;

        };

        {

                Object.seal(refObject );

                //seal封装,对参数对象进行封闭,不能添加新的属性,只能有一个属性

        }

        return refObject;

}

注意:

执行React.creatRef()=>返回{ current:null }对象容器,但是这个返回值源码没有挂载到组件实例上.

所以我们需要进行手动挂载this.key = React.createRef()上

createRef实现自动化时钟

class Clock extends React.Component{

        constructor(props){

                super(props)

                this.timeRef=React.createRef() //{current:null}

        }

        render(){

                return(

                        <div>

通过createElement创建虚拟DOM,新增ref属性,

ReactDOM.render把虚拟DOM同步渲染成真实DOM=>判断是否有ref存在

如果有ref,会把ref对应的值,即{current:null}容器,将真实DOM<h2>赋值给容器current属性

和2的区别:

不需要给引用容器提供key

                                <h2 ref={e=>}>{new Date().toLocalTimeString()}</h2>

                        </div>

                )

        }

        componentDidMount(){

                console.log(this)

                console.log(this.ref)

                setInterval(()=>{

                        //this.key.current=真实DOM<h2>

                        this.timeRef,current.innerHTML = new Date().toLocalTimeString()

                },1000)

        }

}

2.业务场景(登录)=>ref模拟form表单收集

三种非受控表单解决方式

方式一:ref="key"  原理:this.refs={} => this.refs={key:真实DOM}

方式二:ref={e=>this.key=e} =>直接赋值this.key=真实DOM

方式三:直接调用react提供的方法createRef();this.key=React.createRef():{current:nulll}=>{current:真实DOM}

方式一:ref="key"  原理:this.refs={} => this.refs={key:真实DOM}

class Form extends React.Component{

        console.log(this)

        console.log(this.refs.inputRef) //真实DOM

        console.log(this.refs.inputRef.value)

        render(){

                return(

                        <div>

                                <input type="text" ref="inputRef" />

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

}

方式二:ref={e=>this.key=e} =>直接赋值this.key=真实DOM

 class Form extends React.Component{

        console.log(this.inputRef2) //真实DOM

         console.log(this.inputRef2.value) //获取input输入内容

        render(){

                return(

                        <div>

                                <input type="text" ref={e=>this.inputRefs2=e}/>

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

}

方式三:直接调用react提供的方法createRef();this.key=React.createRef()

 class Form extends React.Component{

        console.log(this.inputRef3) //非真实DOM,是个对象容器

         console.log(this.inputRef3.current) //真实DOM

         console.log(this.inputRef3.current.value) //获取input输入内容

        constructor(){

                super()

                this.inputRef3=React.createRef()

        }

        render(){

                return(

                        <div>

                                <input type="text" ref={this.inputRefs3}/>

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

}

事件绑定受控表单方式

  class Form extends React.Component{

        handleChange=>(e)=>{

                console.log("onChange") //input输入框中每输入一个触发一次onChange

                console.log(e.targrt.value)

        }

        render(){

                return(

                        <div>

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

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

}

3.业务衍生场景=>按钮触发事件

class Form extends React.Component{

        constructor(){

                super();

                this.inputRef = React.createRef()

        }

        handleClick=()=>{

                alert( this.inputRef.current.value)

        }

       handleBlur=(e)={

                console.log(e.target) //真实DOM

                console.log(e.target.value) //输入框内容

                 alert(e.target.value);

        }

        render(){

                return(

                        <div>

                                <input type="text" onBlur={this.handleBlur}/>

                                <input type="text" ref={this.inputRef}/>

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

}

ReactDOM.render(<Form />,document.getElementById("app"))

4.业务衍生场景=>表单自动获取焦点

class Form extends React.Component{

        constructor(){

                super();

                this.inputRef = React.createRef()

        }

        handleClick=()=>{

                this.inputRef.current.focus() 

        }

        render(){

                return(

                        <div>

                                <input type="text" ref={this.inputRef}/>

                                <button onClick={this.handleClick}>commit</button>

                        </div>

                )

        }

        //已经渲染完毕,可以直接直接使用真实DOM

        componentDidMount(){

                this.inputRef.current.focus()

        }

}

ReactDOM.render(<Form />,document.getElementById("app"))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值