返回

一分钟轻松搞懂useRef的源码与使用场景

前端

useRef:揭秘React中的强大引用工具

理解useRef:剖析其内部运作原理

React的useRef Hook是一个不起眼的工具,但它却拥有令人惊讶的多功能性。让我们深入探究其源码,揭开它内部运作的神秘面纱。

useRef本质上是一个闭包,它包含一个名为"current"的属性,用于存储当前的引用值。当组件首次渲染时,useRef会创建一个新的引用对象,并将"current"属性设置为"null"。当组件更新时,useRef会复用之前创建的引用对象,并将"current"属性更新为最新的引用值。

useRef的万花筒:广泛的应用场景

useRef的用途极其广泛,使其成为React开发人员的宝贵工具。它可以在以下情况下发挥关键作用:

  • 获取DOM元素的引用
  • 在组件重新渲染时持久保存状态
  • 在组件之间传递引用
  • 创建可变的引用

useRef实战:通过示例掌握其强大功能

1. 驾驭DOM元素:使用useRef获取DOM引用

const ref = useRef();

function MyComponent() {
  return (
    <div ref={ref}>
      Hello world!
    </div>
  );
}

在这个示例中,我们使用useRef为DOM元素分配了一个引用,使我们可以通过"current"属性在组件内部访问该元素。

2. 突破重新渲染的限制:持久保存状态

const countRef = useRef(0);

function MyComponent() {
  countRef.current++;
  return (
    <div>
      Count: {countRef.current}
    </div>
  );
}

即使组件重新渲染,useRef也会保留"countRef"的值,从而使我们能够跟踪组件的状态,不受重新渲染的影响。

3. 组件间无缝衔接:在组件间传递引用

const childRef = useRef();

function ParentComponent() {
  return (
    <div>
      <ChildComponent ref={childRef} />
    </div>
  );
}

function ChildComponent(props) {
  const parentRef = props.ref;
  return (
    <div>
      Parent ref: {parentRef.current}
    </div>
  );
}

useRef允许我们轻松地将引用从父组件传递到子组件,促进组件之间的通信。

4. 灵活应变:创建可变的引用

const ref = useRef({ count: 0 });

function MyComponent() {
  ref.current.count++;
  return (
    <div>
      Count: {ref.current.count}
    </div>
  );
}

useRef可以创建可变的引用,使我们能够在组件生命周期内动态更改引用的值。

拓展功能:useRef与useImperativeHandle和forwardRef的协作

useRef可以与其他React Hooks,如useImperativeHandle和forwardRef,协同工作,以实现更高级的组件交互。

1. useRef与useImperativeHandle的联袂出演

const childRef = useRef();

function ParentComponent() {
  const handleClick = () => {
    childRef.current.focus();
  };

  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={handleClick}>Focus child input</button>
    </div>
  );
}

function ChildComponent(props) {
  const inputRef = useRef();

  useImperativeHandle(props.ref, () => ({
    focus() {
      inputRef.current.focus();
    },
  }));

  return (
    <div>
      <input ref={inputRef} />
    </div>
  );
}

useImperativeHandle允许我们从父组件访问子组件的方法,而useRef则提供了必要的引用。

2. useRef与forwardRef的默契配合

const ChildComponent = React.forwardRef((props, ref) => {
  return (
    <div>
      Child component
    </div>
  );
});

function ParentComponent() {
  const childRef = useRef();

  return (
    <div>
      <ChildComponent ref={childRef} />
      Parent ref: {childRef.current}
    </div>
  );
}

forwardRef允许我们从子组件获取引用,而useRef则存储并访问该引用。

结语:useRef的非凡力量

useRef是一个功能强大的Hook,为React开发人员提供了一个多才多艺的工具。它使我们能够轻松地获取DOM元素的引用、持久保存状态、在组件间传递引用以及创建可变的引用。通过与其他Hooks的协作,useRef成为React组件交互的强大盟友。

常见问题解答

  1. useRef与useState有什么区别?
    useRef存储可变值,不受重新渲染的影响,而useState存储组件状态,会在重新渲染时更新。

  2. 为什么useRef适合获取DOM引用?
    因为useRef创建了一个持久引用,即使组件重新渲染,也能保持引用DOM元素。

  3. useRef如何实现组件间引用传递?
    useRef通过将引用作为prop传递,允许组件之间共享引用。

  4. useRef与useImperativeHandle如何交互?
    useImperativeHandle使父组件能够调用子组件的方法,useRef则提供所需的引用。

  5. useRef与forwardRef如何配合?
    forwardRef允许子组件将引用传递回父组件,useRef存储并访问该引用。