useImperativeHandle 和 forwardRef

封装方法的时候,有用到useImperativeHandle + forwardRef,今天就简单记录一下

forwardRef的使用

用:
1、在Dom button 里声明ref
2、在FancyButton组件里,FancyButton通过使用React.forwardRef来获取Dom传递过来的ref,然后在自己的button元素里用

const ref = React.createRef();
<FancyButton ref= {ref}>Click me </FancyButton>

const FancyButton = React.forwardRef((props,ref)=>{
    <button ref = {ref} className = 'FancyButton'>
        {props.children}
    </button>
})
官网说:

官网链接:https://zh-hans.reactjs.org/docs/forwarding-refs.html
forwardRef 是一个破坏性的更改,可能会引起依赖旧行为的应用和其他库崩溃。所以如果组件库里有其他ref依赖等,需要仔细确认一下。

官网的例子:
1、hoc高阶组件可以将props透传到其包裹的组件
2、但是ref并不能透传,如果对hoc添加ref,ref会被引用到最外层的容器组件,而不是childComponent
3、解决的方法就是React.forwardRef(现在可以明白为啥叫forward组件了),将ref转发到内部的FancyButton。
React.forwardRef 接受一个渲染函数,其接收 props 和 ref 参数并返回一个 React 节点。
function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', 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} />;
  });
}

这个例子最后稍微有点绕,其实想说的意思就是,
{forwardedRef,…rest}被当成pros传入了LogProps,
而且ref可以取出来作为常规的props属性用。

再来看useImperativeHandle 与 forwardRef用法

如果说刚刚的forwardRef是父传子,那么useImperativeHandle 就是子传父,

官网原话是:
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。

用法:useImperativeHandle(ref, createHandle, [deps])

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);

解释:
useImperativeHandle,将ref 和 方法(此处是focus)传给父组件,
FancyInput 就可以使用React.forwardRef来接收传递给他的ref。

在本例中,渲染 的父组件可以调用 inputRef.current.focus()。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值