最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React 中 refs 的常见用法

    正文概述 掘金(好_快)   2021-07-15   413

    一、String 类型的 Refs

    不建议使用,因为 string 类型的 refs 存在一些问题。它已过时并可能会在未来的版本被移除。

    import React from "react";
    // 父组件
    export default class StringRef extends React.PureComponent {
      componentDidMount() {
        console.log("stringRefDom:", this.refs.stringRefDom);
        console.log("stringRefComp:", this.refs.stringRefComp);
      }
      render() {
        return (
          <div>
            {/*原生组件使用方式*/}
            <div ref={"stringRefDom"}>stringRefDom</div>
            {/*类组件使用方式*/}
            <StringRefComp ref={"stringRefComp"} />
          </div>
        );
      }
    }
    //类组件
    class StringRefComp extends React.PureComponent {
      render() {
        return <div>StringRefComp</div>;
      }
    }
    

    二、回调 Refs

    • 如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次
    • 第一次传入参数 null,然后第二次会传入参数 DOM 元素
    • 这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的
    • 通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题
    • 但是大多数情况下它是无关紧要的
    import React from "react";
    // 父组件
    export default class CallbackRef extends React.PureComponent {
      constructor(props) {
        super(props);
        this.callbackRefDom = null;
        this.callbackRefComp = null;
      }
      componentDidMount() {
        console.log("callbackRefDom:", this.callbackRefDom);
        console.log("callbackRefComp:", this.callbackRefComp);
      }
      //回调函数
      setCallbackRefDom = (ref) => {
        this.callbackRefDom = ref;
      };
      setCallbackRefComp = (ref) => {
        this.callbackRefComp = ref;
      };
      //回调函数
      render() {
        return (
          <div>
            <div ref={this.setCallbackRefDom}>callbackRefDom</div>
            <CallbackRefComp ref={this.setCallbackRefComp} />
          </div>
        );
      }
    }
    
    //类组件
    class CallbackRefComp extends React.PureComponent {
      render() {
        return <div>callbackRefComp</div>;
      }
    }
    

    三、React.createRef()

    • React 16.3 版本引入
    • 较早版本的 React,推荐使用回调形式的 refs
    import React from "react";
    // 父组件
    export default class CreateRef extends React.PureComponent {
      constructor(props) {
        super(props);
        this.createRefDom = React.createRef();
        this.createRefComp = React.createRef();
      }
      componentDidMount() {
        console.log("createRefDom:", this.createRefDom.current);
        console.log("createRefComp:", this.createRefComp.current);
      }
      render() {
        return (
          <div>
            <div ref={this.createRefDom}>createRefDom</div>
            <CreateRefComp ref={this.createRefComp} />
          </div>
        );
      }
    }
    //类组件
    class CreateRefComp extends React.PureComponent {
      render() {
        return <div>CreateRefComp</div>;
      }
    }
    

    四、useRef

    • Hook 是 React 16.8 的新增特性
    import React, { useEffect } from "react";
    // 父组件
    const UseRef = React.memo(() => {
      // // 同样可以用
      // const createRefDom = React.createRef();
      // const createRefComp = React.createRef();
      const createRefDom = React.useRef();
      const createRefComp = React.useRef();
      useEffect(() => {
        console.log("useRefDom:", createRefDom.current);
        console.log("useRefComp:", createRefComp.current);
      }, []);
      return (
        <div>
          <div ref={createRefDom}>useRefDom</div>
          <UseRefComp ref={createRefComp} />
        </div>
      );
    });
    
    export default UseRef;
    
    //类组件
    class UseRefComp extends React.PureComponent {
      render() {
        return <div>useRefComp</div>;
      }
    }
    
    

    五、Refs 与函数组件

    • 默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例
    • 如果要在函数组件中使用 ref,你可以使用 forwardRef(可与 useImperativeHandle 结合使用)
    • 或者将该组件转化为 class 组件。
    import React, { useEffect, useImperativeHandle } from "react";
    
    // 父组件
    const ForwardRef = React.memo(() => {
      const createRefComp = React.useRef();
      const createRefCompMethod = React.useRef();
    
      useEffect(() => {
        console.log("useRefComp:", createRefComp.current);
        console.log("createRefCompMethod:", createRefCompMethod.current);
        createRefComp.current.reload();
      }, []);
      return (
        <div>
          <ForwardRefFunc ref={createRefComp} />
        </div>
      );
    });
    
    export default ForwardRef;
    
    const RefFunc = React.forwardRef((props, ref) => {
      const [name, setName] = React.useState(null);
      const reload = () => {
        console.log("reload");
        setTimeout(() => {
          setName("ForwardRefFunc");
        }, 3000);
      };
      //useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值
      useImperativeHandle(ref, () => {
        return {
          reload: reload,
        };
      });
      return <div ref={ref}>ForwardRefFunc {name}</div>;
    });
    const ForwardRefFunc = React.memo(RefFunc);
    
    

    forwardRef 和 useImperativeHandle 最终目的是设法给 ref 提供一个可调用的对象!


    • Refs and the DOM
    • forwardRef
    • useimperativehandle

    起源地下载网 » React 中 refs 的常见用法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元