React 中的 Refs(9)

Refs

允许我们访问真实 DOM

一般的,React 数据流是通过 props 来实现父子组件的交互

Refs 允许我们用于强制修改子组件

// 输入框焦点
class MyInput extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();
  }

  inputOperating() {
    console.log(this.inputRef.current.value);
    this.inputRef.current.focus();
  }

  render() {
    return (
      
); } } // 媒体管理 class MyVideo extends React.Component { constructor() { super(); this.vdoRefs = React.createRef(); } vdoPause() { this.vdoRefs.current.pause(); } vdoPlay() { this.vdoRefs.current.play(); } render() { return (
); } } // 操作动画 class MyBox extends React.Component { constructor(props) { super(props); this.boxRef = React.createRef(); } boxExtend() { const oBox = this.boxRef.current; oBox.style.width = "500px"; oBox.style.height = "500px"; } render() { return ( <>
); } }

createRef 用法细节

  • 通过 createRef 创建 ref 对象
  • 通过元素的 ref 属性可以附加到 React 元素上
  • 一般通过构造器中给 this 赋值一个 ref,方便整个组件使用
  • ref 只要传递 React 元素中,就可以利用 refcurrent 属性访问到该真实 DOM 节点
  • ref 在 componentDidMountcomponentDidUpdate 触发前更新

ref 不同的使用方式:

  • ref 放在 HTML 元素上,则指向真实 DOM 节点
  • ref 放在 class 组件上,则指向组件实例
  • ref 放在函数组件上,不能增加 ref 属性,可以使用 React.useRef()

forwardRef (v16.3 以上版本)

将子组件的 ref 暴露给父组件

React.forwardRef((props, ref) => { return React 元素})
const MyInput = React.forwardRef((props, ref) => (
  // ref 参数只能在,用 forwardRef 定义的组件内可接收
  
));

class App extends React.Component {
  constructor(props) {
    super(props);
    this.myInputRef = React.createRef();
  }
  inputOperate() {
    this.myInputRef.current.value = "";
    this.myInputRef.current.focus();
  }
  render() {
    return (
      
{/* */} {/* */}
); } }
// 高阶组件 ref 转发
class MyInput extends React.Component {
  render() {
    return ;
  }
}

function InputHoc(WarpperComponent) {
  class Input extends React.Component {
    render() {
      const { forwardRef, ...props } = this.props;
      return ;
    }
  }
  function forwardRef(props, ref) {
    return ;
  }

  // 设置别名
  forwardRef.displayName = `Input - ${WarpperComponent.name}`;
  return React.forwardRef(forwardRef);


  // return React.forwardRef((props, ref) => (
  //   
  // ));
}

const MyInputHoc = InputHoc(MyInput);

class App extends React.Component {
  constructor(props) {
    super(props);

    this.myInputRef = React.createRef();
  }

  componentDidMount() {
    console.log(this.myInputRef);
  }

  inputOperate() {
    this.myInputRef.current.value = "";
    this.myInputRef.current.focus();
  }

  render() {
    return (
      <>
        
        
      
    );
  }
}

Refs 转发(v16.2 及以下)

  1. 通过 props 转发
class MyInput extends React.Component {
  render() {
    return ;
  }
}

// 通过 props 转发
class App extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }
  componentDidMount() {
    console.log(this.inputRef);
  }

  render() {
    return (
      
); } }
  1. 回调 Refs
class App extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = null;
  }
  setMyInput(el) {
    this.inputRef = el;
  }
  focusInput() {
    this.inputRef.value = "";
    this.inputRef.focus();
  }
  render() {
    return (
      
); } }
  1. 字符串 refs(不建议使用)
  • 组件实例下面的 refs 集合里的 ref
  • 需要 React 保持跟踪当前正在渲染的组件,this 没法确定
  • React 获取 ref 可能会比较慢
  • 不能在 render 中工作
  • 不能组合,只能设置一个 ref
class App extends React.Component {
  componentDidMount() {
    // 字符串 refs
    console.log(this.refs.inputRef);
  }

  render() {
    console.log(this.refs.inputRef); // undefined
    return (
      
); } }

你可能感兴趣的:(React 中的 Refs(9))