React 中的转发ref

React V16.3� 中react引入了:

  • React.forward((props, ref) => ReactComponent) 用于将组件将refs转发到子组件
  • React.createRef():创建一个ref

这2个APIs,这对父组件中访问子组件中DOM元素提供了极大的便利

普通的使用

在当前组件中使用ref

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // create a ref to store the textInput DOM element
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // Explicitly focus the text input using the raw DOM API
    // Note: we're accessing "current" to get the DOM node
    this.textInput.current.focus();
  }

  render() {
    // tell React that we want to associate the  ref
    // with the `textInput` that we created in the constructor
    return (
      
); } }

通过回调函数的形式将ref传递给子组件中的DOM中

回调refs

function Child(props) {
  return (
    
); } class Parent extends React.Component { componentDidMount() { if (this.textInputRef) this.textInputRef.focus(); } render() { return ( this.textInputRef = el} ); } }

将ref从父组件中转发到子组件中的dom元素上

// FancyButton.js 子组件
import React from 'react';

// 接受props和ref作为参数
// 返回一个React 组件
const FancyButton = React.forwardRef((props, ref) => (
    
));

export default FancyButton;


// 父组件
// app.js
class App extends React.Component {
  
  constructor(props) {
    super(props);
    // 创建一个ref 名字随意
    this.ref = React.createRef();
  }
  
  componentDidMount() {
    console.log('ref', this.ref);
    // this.ref.current 表示获取ref指向的DOM元素
    this.ref.current.classList.add('primary'); // 给FancyButton中的button添加一个class
    this.ref.current.focus(); // focus到button元素上
  }
  
  render() {
    // 直接使用ref={this.fancyButtonRef}
    return (
        子组件
    );
  }
}

在高阶组件中使用转发ref

如果使用了高阶组件,还是按照上面普通的方式使用的话,会导致ref直接转发到高阶组件上,这很明显是错的,我们只需转发多次即可

// 高阶组件
import React from 'react';

function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('先前的属性:', prevProps);
      console.log('当前属性:', this.props);
    }
    
    render() {
      // 使用forwardedRef作为一个ref属性传入组件中
      const { forwardedRef, ...rest } = this.props;
      return (
        
      );
    }
  }
  
  // 使用React.forwardRef对LogProps组件进行转发
  return React.forwardRef((props, ref) => (
    {' 上面定义的LogProps组件接受一个forwarded属性 '}
    
  ));
}



// FancyButton.js 子组件
import React from 'react';
import logProps from './logProps';

// 接受props和ref作为参数
// 返回一个React 组件
const FancyButton = React.forwardRef((props, ref) => (
    
));

// 使用高阶组件对其进行封装
export default logProps(FancyButton);


// 父组件
// app.js
class App extends React.Component {
  
  constructor(props) {
    super(props);
    // 创建一个ref 名字随意
    this.ref = React.createRef();
  }
  
  componentDidMount() {
    console.log('ref', this.ref);
    // this.ref.current 表示获取ref指向的DOM元素
    this.ref.current.classList.add('primary'); // 给FancyButton中的button添加一个class
    this.ref.current.focus(); // focus到button元素上
  }
  
  render() {
    // 直接使用ref={this.fancyButtonRef}
    return (
        子组件
    );
  }
}

可以看出如果需要使用高阶组件,则在高阶组件中也需要对其进行转发。

  • stackblitz react forward ref 在线示例
  • react中文官网 forwarding-refs

你可能感兴趣的:(React 中的转发ref)