React-hooks Refs 使用 二

460 阅读2分钟

React-hooks系列 useRef 使用 二

前言

有时你可能需要访问由React的DOM元素,例如,以聚焦、滚动到它,或测量它的大小和位置。在React中没有内置的方法来完成这些事情,因此需要Refs去操作DOM节点。

目录

一、 怎么挂载Refs到Dom结点

二、如何在遍历JSX时对每个item加ref

三、 如何访问别的组件的Refs

四、 Refs操作Dom的注意事项

怎么挂载Refs到Dom结点

  1. 先引入useRef
import { useRef } from 'react';
  1. 调用useRef,
const myRef = useRef(0);

3.绑定Refs到对应的html

<div ref={myRef}>

4.使用浏览器的api

// You can use any browser APIs, for example:
myRef.current.scrollIntoView();

二、如何在遍历JSX时对每个item加ref

如果我们想要遍历中设置ref。

<ul>
  {items.map((item) => {
    // Doesn't work!
    const myRef = useRef(null);
    return <li ref={myRef} />;
  })}
</ul>

以上方法是不正确的,原因是useRefhook,应该放在顶层,但是如果放在顶层,myRef就会一直被覆盖。下面介绍两种解决方案。

1、把 ref绑定在遍历jsx的父元素,再对子元素操作。

但是,如果DOM结构发生变化,这种方法会变得很脆弱,可能会出现遍历中断。

<ul ref={myRef}>
  {items.map((item) => {
    const myRef = useRef(null);
    return <li/>;
  })}
</ul>


//example use it
listRef.current.lastChild.scrollIntoView

2、用map去记录每个list的每个ref

<ul >
  {items.map((item) => {
    return <li 
                key={id}
                ref={(node) => {
                myRef.current = new Map();
                const map = myRef.current;
                if (node) {
                  map.set(id, node);
                } else {
                  map.delete(id);
                }
           }}
    />;
  })}
</ul>


 //example use it
 const map = myRef.current;
 const node = map.get(id);
 node.scrollIntoView();
    

三、 如何访问别的组件的Refs

import { useRef } from 'react';

function MyInput(props) {
  
  return <input {...props} />;
}

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

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

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

上面这段代码,在控制台打开会提示报错信息。

image.png

要想在MyInput组件中使用父组件的ref,则需要再MyInput引入forwardRef

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

四、 Refs操作Dom的注意事项

Refs是一个逃生口。你应该只在必须走出React时才使用它们。常见的例子包括聚焦问题、滚动位置或调用React不公开的浏览器api。

如果你只是操作聚焦和滚动这样的非破坏性操作,你不会遇到任何问题。但是,如果你尝试手动修改DOM,您可能会面临与React自身操作最后导致冲突的风险。

至此关于reactRefs内容赞告一段落。