React学习笔记:ref和forwardref(二)

597 阅读2分钟

在React框架下直接操作dom需要通过设置ref节点来货标签本身
forwardRef的作用则是转发ref到其指定的组件内。 ref虽然是放置在标签内但是并不会作为props被传递
如需在组件最上层获取到深度嵌套的标签那就需要通过forwardRef进行ref转发
dom节点会被放置在ref.current里

一级嵌套获取dom节点

类里使用ref

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();  
    }

  handleSubmit(event) {
        alert('A name was submitted: ' + this.input.current.value);  
        event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

函数式组件使用ref

import {useRef} from 'React';
function CustomTextInput(props) {
  // 这里必须声明 textInput,这样 ref 才可以引用它  
  const textInput = useRef(null);
  function handleClick() {
    textInput.current.focus();  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} />      
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}
  1. 初始化组件编写render函数
  2. 在类的constructor中使用React.creatRef()接受Ref
    这里强调一下ref获取的时间

React 会在组件挂载时给 current 属性传入 DOM 元素,
并在组件卸载时传入 null 值。
ref 会在 componentDidMount 或 componentDidUpdate 生命周期钩子触发前更新。 Tips 如果在没有组件挂载前调用会报错喔。

  1. 当组件渲染完毕之后就会获得dom节点啦。

多级嵌套获取子组件内标签

//MyForwardRef.js
const myBtn = React.forwardRef((props, btnRef) => {
  return (
    <button ref={btnRef} className="FancyButton">
      {props.children}
    </button>

  )
})
function logProps(Component) {
  class LogProps extends React.Component {
    componentDidMount() {
      console.log(this.props)
    }
    render() {
      const { forwardedRef, ...rest } = this.props;

      // 将自定义的 prop 属性 “forwardedRef” 定义为 ref
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  // 注意 React.forwardRef 回调的第二个参数 “ref”。
  // 我们可以将其作为常规 prop 属性传递给 LogProps,例如 “forwardedRef”
  // 然后它就可以被挂载到被 LogProps 包裹的子组件上。
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}
export default logProps(myBtn);
  1. 首先编写一个内部组件叫做myBtn
  2. 编写calss组件接受外部componet
  3. 在class组件的render函数里面解构出forwardRef
  4. 将forwardRef放置在传递过来的组件标签上。
  5. 将其export给外部
<MyForwardRef 
    name='tht' 
    ref={this.btnRef} >
    clickme
</MyForwardRef>
  1. 最后一步调用就行啦

这里用了高阶组件嵌套来更详细的标识ref转发。其实还有其他更为便捷的方式。
可以查阅下官网的详细文档。 转发Ref
打开控制台看日志信息。 //这是logProps的componentDidMount打印出来的

image.png