React中Hooks几个有用的 ref

先看下来自官方的介绍,当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 ref

  • 如何向组件添加 ref
  • 如何更新 ref 的值
  • ref 与 state 有何不同
  • 如何安全地使用 ref

1.给你的组件添加 ref 

你可以通过从 React 导入 useRef Hook 来为你的组件添加一个 ref:

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('你点击了 ' + ref.current + ' 次!');
  }

  return (
    <button onClick={handleClick}>
      点击我!
      {ref.current}
    </button>
  );
}

在你的组件内,调用 useRef Hook 并传入你想要引用的初始值作为唯一参数。这里的 ref 引用的值是“0”,点击后也不变。

以下是 state 和 ref 的对比:

ref state
useRef(initialValue)返回 { current: initialValue } useState(initialValue) 返回 state 变量的当前值和一个 state 设置函数 ( [value, setValue])
更改时不会触发重新渲染 更改时触发重新渲染。
可变 —— 你可以在渲染过程之外修改和更新 current 的值。 “不可变” —— 你必须使用 state 设置函数来修改 state 变量,从而排队重新渲染。
你不应在渲染期间读取(或写入) current 值。 你可以随时读取 state。但是,每次渲染都有自己不变的 state 快照

2.使用 ref 操作 DOM

由于 React 会自动处理更新 DOM 以匹配你的渲染输出,因此你在组件中通常不需要操作 DOM。但是,有时你可能需要访问由 React 管理的 DOM 元素 —— 例如,让一个节点获得焦点、滚动到它或测量它的尺寸和位置。在 React 中没有内置的方法来做这些事情,所以你需要一个指向 DOM 节点的 ref 来实现。

 

示例: 使文本输入框获得焦点 

在本例中,单击按钮将使输入框获得焦点:

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        聚焦输入框
      </button>
    </>
  );
}

如何使用 ref 回调管理 ref 列表

  • 这里使用map搭配useRef作存储 
import { useRef } from 'react';

export default function CatFriends() {
  const itemsRef = useRef(null);

  function scrollToId(itemId) {
    const map = getMap();
    const node = map.get(itemId);
    node.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  function getMap() {
    if (!itemsRef.current) {
      // 首次运行时初始化 Map。
      itemsRef.current = new Map();
    }
    return itemsRef.current;
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToId(0)}>
          Tom
        </button>
        <button onClick={() => scrollToId(5)}>
          Maru
        </button>
        <button onClick={() => scrollToId(9)}>
          Jellylorum
        </button>
      </nav>
      <div>
        <ul>
          {catList.map(cat => (
            <li
              key={cat.id}
              ref={(node) => {
                const map = getMap();
                if (node) {
                  map.set(cat.id, node);
                } else {
                  map.delete(cat.id);
                }
              }}
            >
              <img
                src={cat.imageUrl}
                alt={'Cat #' + cat.id}
              />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

const catList = [];
for (let i = 0; i < 10; i++) {
  catList.push({
    id: i,
    imageUrl: 'https://placekitten.com/250/200?image=' + i
  });
}

itemsRef 保存的不是单个 DOM 节点,而是保存了包含列表项 ID 和 DOM 节点的 Map。(Ref 可以保存任何值!) 每个列表项上的 ref 回调负责更新 Map。

3.访问另一个组件的 DOM 节点 

当你将 ref 放在像 <input /> 这样输出浏览器元素的内置组件上时,React 会将该 ref 的 current 属性设置为相应的 DOM 节点(例如浏览器中实际的 <input /> )。

但是,如果你尝试将 ref 放在 你自己的 组件上,例如 <MyInput />,默认情况下你会得到 null。这个示例演示了这种情况。请注意单击按钮 并不会 聚焦输入框:

相关推荐

  1. ReactHooks有用 ref

    2024-07-19 06:56:03       20 阅读
  2. reactrefs作用是什么?有种用法?

    2024-07-19 06:56:03       45 阅读
  3. React常见Hook

    2024-07-19 06:56:03       40 阅读
  4. react,hooksuseRef使用

    2024-07-19 06:56:03       41 阅读
  5. react hook 为循环出来多个子组件添加ref

    2024-07-19 06:56:03       40 阅读
  6. 回调形式 RefsReact 应用

    2024-07-19 06:56:03       51 阅读
  7. react hooksuseContext

    2024-07-19 06:56:03       56 阅读
  8. react hooks useMemo:

    2024-07-19 06:56:03       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 06:56:03       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 06:56:03       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 06:56:03       62 阅读
  4. Python语言-面向对象

    2024-07-19 06:56:03       72 阅读

热门阅读

  1. Android RecyclerView实现Item单条滑动,一屏滑动

    2024-07-19 06:56:03       19 阅读
  2. crc、ecc、 uboot和 boot的原理分析及详解

    2024-07-19 06:56:03       23 阅读
  3. React Hook 总结(React 萌新升级打怪中...)

    2024-07-19 06:56:03       23 阅读
  4. linux路由基础知识(一)

    2024-07-19 06:56:03       18 阅读
  5. Activiti7+ SpringBoot+SpringMVC 开发

    2024-07-19 06:56:03       19 阅读
  6. AWS backup服务和 RDS snapshot的关系

    2024-07-19 06:56:03       22 阅读
  7. 低代码前端框架Amis全面教程

    2024-07-19 06:56:03       17 阅读
  8. git-各种场景-撤销指令

    2024-07-19 06:56:03       20 阅读