react 16.8 新特性总结(二)掌握useref和ref

在react 中主要时操作数据进行操作,但是会有许多情况下我们还是需要获取dom,所以我们会用到ref

ref

ref的作用
Ref属性用来获取DOM 元素的节点和获取子组件的实例
我们先来看在class 组件中的ref

  • refs时使用React.create()创建的,并通过ref属性附加到React 元素中,在构建组件时,通常将Refs 分配给属性实例,以便在整个组件中华引用它们
  • 当ref被传递给render中的元素时,改节点可以在ref的current属性中被访问
  • React 会在组件挂载时给current属性传入DOM元素,并在卸载时传入null 值。
  • ref会在componentDidMOunt或者componentDidUpdate生命周期的钩子函数触发

获取DOM元素节点:

import React, { Component, createRef} from "react";
class App extends Component {
  constructor(props) {
    super(props);
    this.h1Ref = createRef();
  }
  componentDidMount() {
    console.log("React.createRef()");
    console.log(this.h1Ref.current);
  }
  render() {
    return <h1 ref={this.h1Ref}>Hello World!</h1>;
  }
}
export default App;

结果
在这里插入图片描述

获取子组件实例

import React, { Component, createRef } from "react";
class App extends Component {
  constructor(props) {
    super(props);
    this.childRef = createRef();
  }
  componentDidMount() {
    console.log("React.createRef()");
    console.log(this.childRef.current);
    this.childRef.current.handleLog();
  }
  render() {
    return (
      <div>
        <h1>Hello World!</h1>
        <Child ref={this.childRef} count="1" />
      </div>
    );
  }
}
class Child extends Component {
  handleLog = () => {
    console.log("Child Component");
  };
  render() {
    const { props } = this;
    return <h1>count: {props.count}</h1>;
  }
}
export default App;

结果
在这里插入图片描述

useRef

  • 在函数组件中使用String Ref,Callback Ref , Create Ref 会抛出错误这个是因为函数组件中没有实例,所以函数组件中无法使用Create Ref

useRef的作用

  • 获取DOM元素的节点
  • 获取子组件的共享实例
  • 渲染周期之间共享数据(state 不能寸尺跨渲染周期的数据,因为state的保存会触发组件的重新渲染)

获取DOM元素的节点

import React, { useEffect, useRef } from 'react';
function App() {
  const h1Ref = useRef();
  useEffect(() => {
    console.log('useRef')
    console.log(h1Ref.current)
  }, [])
  return <h1 ref={h1Ref}>Hello World!</h1>
}
export default App;

结果:
在这里插入图片描述

获取组件实例:

注: 因为函数组件没有实例,如果想用ref获取子组件的实例,子组件组要写成类组件。

import React, { Component, useEffect, useRef } from 'react';
function App() {
  const childRef = useRef();
  useEffect(() => {
    console.log('useRef')
    console.log(childRef.current)
    childRef.current.handleLog();
  }, [])
  return (
    <div>
      <h1>Hello World!</h1>
      <Child ref={childRef} count="1"/>
    </div>
  )
}
// 因为函数组件没有实例,如果想用ref获取子组件的实例,子组件组要写成类组件
class Child extends Component {
  handleLog = () => {
    console.log('Child Component');
  }
  render() {
    const { count } = this.props;
    return <h2>count: { count }</h2>
  }
}
export default App;

结果:
在这里插入图片描述

渲染周期之间共享数据的存储

在类组件中,state 不嫩存储跨渲染周期的组件,因为state 的参数每一次保存都会触发组件的重渲染。
场景:声明一个参数为count = 0 ,组件初始化时count每秒钟加1,直到count > 5时停止增加,清除定时器。
把定时器设置成全局变量使用useRef挂载到current上

import React, { useState, useEffect, useRef } from "react";
function App() {
  const [count, setCount] = useState(0);
  // 把定时器设置成全局变量使用useRef挂载到current上
  const timer = useRef();
  // 首次加载useEffect方法执行一次设置定时器
  useEffect(() => {
    timer.current = setInterval(() => {
      setCount(count => count + 1);
    }, 1000);
  }, []);
  // count每次更新都会执行这个副作用,当count > 5时,清除定时器
  useEffect(() => {
    if (count > 5) {
      clearInterval(timer.current);
    }
  });
  return <h1>count: {count}</h1>;
}
export default App;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值