React中Refs学习(二)

本文深入探讨React中Refs的高级用法,包括如何通过回调Refs实现对DOM节点的精细控制,以及在高阶组件中正确使用Refs的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每个项目产品都要加埋点,加500行埋点是不是会占用你一两天的时间而且很容易犯错,想只用一小时准确加完这500行埋点剩下一天喝茶聊天么?来试试这520web工具, 高效加埋点,目前我们公司100号前端都在用,因为很好用,所以很自然普及开来了,推荐给大家吧

http://www.520webtool.com/

自己开发所以免费,埋点越多越能节约时间,点两下埋点就加上了,还不会犯错,里面有使用视频,反正免费 😄

React中Refs学习(二)

一月 23, 2019 by Fakin

上篇文章我们说到react中refs一些基本的知识,本篇文章我们学习refs进阶知识!这也是年前最后一篇文章了!

对父组件暴露节点

大多数情况下,我们不需要让子组件对父组件暴露DOM,而且React也不太支持我们这么做(尽管这是可行的),但是有些情况你又非得这么做,比如:让子组件input自动获得焦点亦或者你必须知道子组件的位置和大小!

function children(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <children
        inputRef={el => this.inputElement = el}
      />
    );
  }
}

需要注意的是,如果你直接在子组件上添加ref然后在父组件上获取,获取到的将会是子组件实例而不是你需要的Dom节点,所以这时候我们需要在子组件上暴露一个特殊的属性,然后让父组件获取。

回调refs

在上一篇中有说到函数式组件无法使用ref,但是你可以在函数式组件内部使用ref,这个时候ref必须指向Dom元素或者class。这是也就是回调了。

函数式组件内部使用ref

function Fakin(props) {
  // 这里必须声明 textInput,这样 ref 回调才可以引用它
  let textInput = null;

  function handleClick() {
    textInput.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={(input) => { textInput = input; }} />

      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}

类组件中ref回调示例

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = null;
    this.setTextInputRef = element => {//ref回调函数
      this.textInput = element;
    };
    this.focusTextInput = () => {
      if (this.textInput) this.textInput.focus();//自动获得焦点
    };
  }
  componentDidMount() {
    this.focusTextInput();
  }
  render() {
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}
        />
      </div>
    );
  }
}

这段代码的意思是打开页面input自动获得焦点,ref={this.setTextInputRef}this.setTextInputRefthis.textInput指向了DOM元素(input)。

那有人要说了,你这个用ref回调和我直接写ref={xxx}有什么区别啊,都可以做到相同的事情!

React是这么描述refs回调的

which gives more fine-grain control over when refs are set and unset.

意思是ref回调可以对何时设置和取消引用进行更精细的控制。

在上面这段代码中,React会在组件挂载时用DOM元素调用ref回调,组件卸载的时候把ref设置为null,从而能更加精确的控制!

高阶组件的refs

好像博主的文章还没涉及高阶组件,不管了,先简单的介绍了高阶组件吧。

高阶组件:获取一个组件并返回一个新的组件

咦,这不就是纯函数吗。

function fakin(ChildrenComponent) {
  class Fakin extends React.Component {
    render() {
      return <ChildrenComponent {...this.props} />;
    }
  }
  return Fakin;
}

在HOC(高阶组件中使用refs,父组件获取子组件的dom)

function fakin(Component) {

  class Fakin extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  return React.forwardRef((props, ref) => {
    return <Fakin {...props} forwardedRef={ref} />;
  });
}

在类组件Fakin中正常返回<Component ref={forwardedRef} {...rest} />;而且ref书写
最后咱们使用React.forwardRef这个方法来显示将refs转发到内部组件。否则refs指向的是Fakin这个HOC

补充

React.createRef()创建ref

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

访问refs

const myRef = this.myRef.current;

React.forwardRef创建一个React,同时接收一个函数作为参数,该函数有两个参数(prop,ref),该函数返回一个React节点,把两个参数(prop,ref)作为节点的(prop,ref)

const Button = React.forwardRef((props, ref) => (
  <button ref={ref} className="Button">
    {props.children}
  </button>
));

const ref = React.createRef();
<Button ref={ref}>点击我</Button>;

这一点React不希望我们这么做,但是在HOC中有时候不得不这么做~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值