这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战
翻译自:beta.reactjs.org/learn/manip…
因为 React 已经根据 render 的输出处理了 DOM 结构,所以你的组件不经常需要操作 DOM。然而,有的时候你可能需要操作 React 管理的 DOM 元素,比如,将焦点放到一个节点上,滚动到这个节点,或者去计算它的宽和高。React 中没有内置的方法去做这些事情,所以你将会需要 ref 去指向这个 DOM 节点。
这个系列的文章你将会学到:
- 如何使用 ref 属性访问由 React 管理的 DOM 节点
- 如何将 JSX 的
ref
属性关联到useRef
钩子 - 如何访问其他组件的 DOM 节点
- 在哪种情况下,修改 React 管理的 DOM 是安全的
关于 ref 相关的介绍和例子,可以看我前面一个系列的文章 useRef 简单易懂解析
系列文章
- 如何使用 ref 操作 DOM?(一)使用 ref 访问 DOM 节点
- 如何使用 ref 操作 DOM?(二)使用示例
- 如何使用 ref 操作 DOM?(三)如何使用 ref 回调去管理列表的 ref
- 如何使用 ref 操作 DOM?(四)forwardRef 访问自己组件的 DOM 节点
- 如何使用 ref 操作 DOM?(五)原理、react state 同步更新 DOM 的方式
使用 refs 操作 DOM 的最佳实践
Refs 是一个逃生口,你应该只在你必须“走出 React”时使用它们。这方面的常见示例包括管理焦点(focus)、滚动到某个位置或调用 React 未公开的浏览器 API。
如果你使用聚焦(focus)和滚动等非破坏性操作,您应该不会遇到任何问题。但是,如果您尝试手动修改 DOM,则可能会与 React 所做的更改发生冲突。
为了说明这个问题,这个例子包括一条欢迎消息和两个按钮。第一个按钮使用条件渲染和 state 切换消息是否可见,就像你通常在 React 中所做的那样。第二个按钮使用 remove()
DOM API 将其从 React 控制之外的 DOM 中强行移除。
尝试按“Toggle with setState”几次。该消息应该消失并再次出现。然后按“Remove from the DOM”。这将强行删除它。最后,按“Toggle with setState”:
import {useState, useRef} from 'react';
export default function Counter() {
const [show, setShow] = useState(true);
const ref = useRef(null);
return (
<div>
<button
onClick={() => {
setShow(!show);
}}>
Toggle with setState
</button>
<button
onClick={() => {
ref.current.remove();
}}>
Remove from the DOM
</button>
{show && <p ref={ref}>Hello world</p>}
</div>
);
}
手动删除 DOM 元素后,尝试使用 setState
再次显示它会导致崩溃。这是因为您更改了 DOM,而 React 不知道如何继续正确管理它。
避免更改 React 管理的 DOM 节点。,修改、向 React 管理的元素添加子元素或从元素中删除子元素可能会导致不一致的视觉结果或与上述类似的崩溃。
但是,这并不意味着您完全不能这样做。它需要谨慎。你可以安全地修改 React 没有理由更新的部分 DOM。 例如,如果某些 <div>
在 JSX 中总是空的,React 就没有理由去触摸它的子列表。因此,在那里手动添加或删除元素是安全的。