《React-hook-useRef》

491 阅读2分钟

一. useRef

const refContainer = useRef(initialValue);

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

如果需要一个值,在组件不断render时保持不变,那就可以使用useRef

本质上,useRef 就像是可以在其 .current 属性中保存一个可变值的“盒子”。

我们改变的只是refContainer.current这个属性的值。refContainer在每次渲染时的地址是不变的。useRef 会在每次渲染时返回同一个 ref 对象。

请记住,当 ref 对象内容发生变化时,useRef 并不会通知你。变更 .current 属性不会引发组件重新渲染。只能自己手动渲染。比如在变更.current之后,再随便setState一个数据,这会使App再次执行。

二. forwardRef

1. 函数组件无法接收ref的props

function App() {
  const buttonRef = useRef(null);
  return (
    <div className="App">
      <Button2 ref={buttonRef}>按钮</Button2>
    </div>
  );
}

const Button2 = props => {
  console.log(props);
  return <button className="red" {...props} />;
};

在App里useRef得到一个buttonRef对象,把它传给Button2组件,我就想让buttonRef引用到Button2对应的DOM对象。

可是控制台报错了,说函数组件不能接受refs的外部数据。我们打印出Button2的props,发现只有按钮被传进来了,ref没进来。外边虽然给我传了一个ref,但是我是一个函数组件,我找不到这个ref,读不到。

2. 使用 forwardRef传递ref

如果你的函数组件想要接受别人传来的ref参数,就必须把函数组件用forwardRef包起来。这样就可以接受ref作为第二个参数。不然就只有props这一个参数。forwardRef会把别人传给你的ref帮你传进来。

const Button2=React.forwardRef((props,ref)=>{
  console.log(props);
  console.log(ref)
  return <button className="red" ref={ref}/>;
})

打印ref,由于传进来的ref参数已经被绑定到了button元素的ref属性上,所以打印出来的ref.current就是button这个DOM节点

类组件是不需要的,可以直接传。