2022即将到来,前端发展非常迅速,现在的前端已经不再是写写简单的页面了,伴随着web大前端,工程化越来越火,也出现了很多框架。很多公司也不单单是使用单一的框架了,作为前端开发国内最火的两大框架,都是必须要掌握的。所以,我决定在这疫情肆虐的年底把React学习一下,也为自己将来找工作多一分竞争力...
学习阶段,如有不对之处,欢迎评论区留言,我及时更正
本文已连载,其它章节传送门⬇️
Ref和Refs
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素,React中的ref类似于vue中的ref,都可以通过给组件或者Dom绑定ref获取到此组件实例
注意:字符串形式的ref已经弃用
我们有三种方法可以创建ref,分别为:字符串形式的ref(已弃用)、回调形式的ref、createRef
字符串形式的ref
export default class Demo extends Component {
componentDidMount(){
console.log(this.refs.Index)
}
render() {
return (
<div>
<Index ref="Index"></Index>
</div>
)
}
}
class Index extends Component {
render() {
return (
<div>
<button>Index按钮</button>
</div>
)
}
}
我们可以给组件绑定ref属性,在
componentDidMount
钩子函数中通过this.refs.绑定ref名
访问到组件实例,打印结果可以看到,但是此方法已弃用,官网也有说明此方法会有一些问题
回调形式的ref
export default class Demo extends Component {
constructor(props){
super(props)
this.indexDOM = null
}
getIndexRef = (element) => {
console.log(element, 'getIndexRef函数执行了')
this.indexDOM = element
}
render() {
return (
<div>
<Index ref={this.getIndexRef}></Index>
</div>
)
}
}
class Index extends Component {
render() {
return (
<div>
<button>Index按钮</button>
</div>
)
}
}
借用上面的图片吧,也是可以正常打印能拿到组件。但是如果ref的回调函数是内联形式的,更新过程中,会被执行两次,第一次传入null,第二次传入dom节点,这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题
我们修改下代码:
export default class Demo extends Component {
constructor(props){
super(props)
this.indexDOM = null
this.state = {
count: 0
}
}
getIndexRef = (element) => {
console.log(element, 'getIndexRef函数执行了')
this.indexDOM = element
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<Index ref={e => this.getIndexRef(e)} changeCount={this.handleClick} count={this.state.count}></Index>
</div>
)
}
}
class Index extends Component {
render() {
return (
<div>
<h1>当前count:{this.props.count}</h1>
<button onClick={this.props.changeCount}>Index按钮</button>
</div>
)
}
}
第一次正常打印,当我点击按钮触发组件更新的时候,可以看到 ref的内联回调函数执行了两次且第一次拿到的是null
createRef
通过React.createRef
创建并绑定ref,也可以访问到组件节点,官网推荐使用此方法
export default class Demo extends Component {
constructor(props){
super(props)
this.myIndex = React.createRef()
}
componentDidMount() {
console.log(this.myIndex.current)
}
render() {
return (
<div>
<Index ref={this.myIndex}></Index>
</div>
)
}
}
class Index extends Component {
render() {
return (
<div>
<button>Index按钮</button>
</div>
)
}
}