# React技巧之使用ref获取元素宽度
原文链接:https://bobbyhadz.com/blog/react-get-element-width-ref (opens new window)
作者:Borislav Hadzhiev (opens new window)
正文从这开始~
# 总览
在React中,使用ref获取元素的宽度:
- 在元素上设置
ref属性。 - 在
useLayoutEffect钩子中,更新宽度的state变量。 - 使用
offsetWidth属性获取元素宽度。
import {useLayoutEffect, useRef, useState} from 'react';
export default function App() {
const ref = useRef(null);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
useLayoutEffect(() => {
setWidth(ref.current.offsetWidth);
setHeight(ref.current.offsetHeight);
}, []);
return (
<div ref={ref}>
<h2>Width: {width}</h2>
<h2>Height: {height}</h2>
</div>
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
useRef()钩子可以传递一个初始化作为参数。该钩子返回一个可变ref对象,其.current属性被初始化为传递的参数。
请注意,我们必须访问
ref对象的current属性,以获得对我们设置ref属性的div元素的访问。
当我们为元素传递ref属性时,比如说,<div ref={myRef} /> 。React将ref对象的.current属性设置为相应的DOM节点。
# useLayoutEffect
我们传递一个空的依赖数组到useLayoutEffect 钩子上,所以它只会在组件挂载时运行。
useLayoutEffect(() => {
setWidth(ref.current.offsetWidth);
setHeight(ref.current.offsetHeight);
}, []);
2
3
4
useLayoutEffect钩子与useEffect相同,但在所有DOM突变后同步触发。useLayoutEffect 钩子经常被用来从DOM中读取布局。
我们使用了useLayoutEffect钩子,因为我们需要等待元素上的ref被设置,并且在访问其offsetHeight和offsetWidth属性之前,元素被渲染。
offsetWidth属性以像素为单位返回元素的宽度,包括任何边框、内填充和垂直滚动条(如果存在的话)。
offsetHeight属性返回元素的高度,单位是像素,包括垂直内填充和边框。
或者,你可以使用clientWidth属性,它返回元素的宽度,单位是像素,包括内填充,但不包括边框、外边距和垂直滚动条(如果存在的话)。
useLayoutEffect(() => {
setWidth(ref.current.clientWidth);
setHeight(ref.current.clientHeight);
}, []);
2
3
4
# 总结
我们通过ref来获取元素的宽度和高度,主要是在useLayoutEffect钩子中通过ref.current来引用DOM元素,获取元素上面的offsetWidth和offsetHeight 。