P17:React高级-ref 的用法和 ref 中的坑
Posted wgchen~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P17:React高级-ref 的用法和 ref 中的坑相关的知识,希望对你有一定的参考价值。
React16 基础
阐述
在编写组件中的方法时,经常会遇到语义化很模糊的代码,这对于团队开发是一个很大的问题。因为 review
代码或者合作时都会影响开发效率。或者核心成员离开,项目倒闭的严重影响。所以我们必须重视react代码当中的语义化。
ref
是个不错的工具,快来学习一下吧。
代替原来的 e.target.value
以前的案例中,我们写了下面的代码,使用了 e.target
,这并不直观,也不好看。这种情况我们可以使用 ref
来进行解决。
inputChange(e)
this.setState(
inputValue:e.target.value
)
如果要使用 ref
来进行,需要先在JSX中进行绑定, 绑定时最好使用ES6语法中的箭头函数,这样可以简洁明了的绑定DOM元素。
<input
id="willem"
className="input"
value=this.state.inputValue
onChange=this.inputChange.bind(this)
//关键代码——----------start
ref=(input)=>this.input=input
//关键代码------------end
/>
绑定后可以把上边的类改写成如下代码:
inputChange()
this.setState(
inputValue:this.input.value
)
这就使我们的代码变得语义化和优雅的多。
但是就我个人的经验来讲,我是不建议用 ref
这样操作的,因为React的是数据驱动的,所以用 ref
会出现各种问题。
import React,Component,Fragment from 'react'
import BeautyItem from './BeautyItem'
class Beauty extends Component
//js的构造函数,由于其他任何函数执行
constructor(props)
super(props) //调用父类的构造函数,固定写法
this.state=
inputValue:'' , // input中的值
list:['基础按摩','精油推背'] //服务列表
render()
return (
<Fragment>
/* 正确注释的写法 */
<div>
<label htmlFor="willem">加入服务:</label>
<input
id="willem"
className="input"
value=this.state.inputValue
onChange=this.inputChange.bind(this)
//关键代码——----------start
ref=(input)=>this.input=input
//关键代码------------end
/>
<button onClick=this.addList.bind(this)> 增加服务 </button>
</div>
<ul>
this.state.list.map((item,index)=>
return (
<BeautyItem
key=index+item
content=item
index=index
deleteItem=this.deleteItem.bind(this)
/>
)
)
</ul>
</Fragment>
)
// inputChange(e)
// // console.log(e.target.value);
// // this.state.inputValue=e.target.value;
// this.setState(
// inputValue:e.target.value
// )
//
inputChange()
console.log(this.input.value);
this.setState(
inputValue:this.input.value
)
//增加服务的按钮响应方法
addList()
this.setState(
list:[...this.state.list,this.state.inputValue],
inputValue:''
)
//删除单项服务
deleteItem(index)
let list = this.state.list
list.splice(index,1)
this.setState(
list:list
)
export default Beauty
ref 使用中的坑
比如现在我们要用 ref
绑定取得要服务的数量,可以先用 ref
进行绑定。
<ul ref=(ul)=>this.ul=ul>
this.state.list.map((item,index)=>
return (
<BeautyItem
key=index+item
content=item
index=index
deleteItem=this.deleteItem.bind(this)
/>
)
)
</ul>
绑定后可以在 addList()
方法中,获取当前 <li>
的值.
ddList()
this.setState(
list:[...this.state.list,this.state.inputValue],
inputValue:''
)
//关键代码--------------start
console.log(this.ul.querySelectorAll('li').length)
//关键代码--------------end
这时候你打开控制台,点击添加服务按钮,你会发现数量怎么少一个?
(就是这个坑)如下图,
其实这个坑是因为React中更多 setState
是一个异步函数所造成的。
也就是这个 setState
,代码执行是有一个时间的,如果你真的想了解清楚,你需要对什么是虚拟DOM有一个了解。简单的说,就是因为是异步,还没等虚拟Dom渲染,我们的console.log
就已经执行了。
那这个代码怎么编写才会完全正常那,其实setState
方法提供了一个回调函数,也就是它的第二个函数。
下面这样写就可以实现我们想要的方法了。
addList()
this.setState(
list:[...this.state.list,this.state.inputValue],
inputValue:''
//关键代码--------------start
,()=>
console.log(this.ul.querySelectorAll('li').length)
)
//关键代码--------------end
现在到浏览器中查看代码,就完全正常了。
总结
本文主要学习了 ref
的用法和 ref
中的坑。
学完后练习一下吧,代码这东西,不练习你是学不会的。
以上是关于P17:React高级-ref 的用法和 ref 中的坑的主要内容,如果未能解决你的问题,请参考以下文章