2023-06-29 17:24:27
在React函数组件中,无需事件监听器即可通过useRef钩子直接获取DOM元素,实现如自动调整文本区域高度等操作。
1. 核心问题:为何需要useRef?在函数组件中,直接操作DOM的需求通常出现在以下场景:
示例场景:自动调整高度的文本区域。若仅依赖onChange,无法在组件初次渲染或通过props更新内容时触发高度调整。
2. 解决方案:useRef钩子的作用与原理useRef返回一个可变的ref对象,其.current属性在组件生命周期内保持稳定,用于存储DOM引用或其他可变值。
将ref对象传递给JSX元素的ref属性,React会在元素挂载时将DOM节点赋值给ref.current,卸载时设为null。
通过ref.current可直接访问DOM,无需依赖事件监听器。
以自动调整高度的文本区域为例,步骤如下:
步骤1:导入useRefimport React, { useState, useEffect, useRef } from 'react';步骤2:创建ref对象在函数组件内部调用useRef(),初始化为null:
const textareaRef = useRef(null);步骤3:关联ref到DOM元素将ref对象传递给目标DOM元素(如<textarea>):
<Form.Control ref={textareaRef} as="textarea" style={textareaStyle} />步骤4:在useEffect中使用ref通过ref.current访问DOM,执行操作(如调整高度):
useEffect(() => { const autoGrow = () => { if (textareaRef.current) { const element = textareaRef.current; element.style.height = "5px"; // 重置高度以计算实际内容高度 element.style.height = `${element.scrollHeight}px`; // 设置为滚动高度 } }; autoGrow();}, [text]); // 依赖text状态变化完整代码示例:
import React, { useState, useEffect, useRef } from 'react';import { Container, InputGroup, Form } from 'react-bootstrap';const textareaStyle = { resize: "none", overflow: "hidden", minHeight: "50px", maxHeight: "1000px"};function ChatInput(props) { const [text, setText] = useState(''); const textareaRef = useRef(null); const autoGrow = () => { if (textareaRef.current) { const element = textareaRef.current; element.style.height = "5px"; element.style.height = `${element.scrollHeight}px`; } }; useEffect(() => { setText(props.answer || ''); }, [props.answer]); useEffect(() => { autoGrow(); }, [text]); return ( <Container style={{ paddingTop: '.5rem' }}> <InputGroup> <InputGroup.Text>Bot</InputGroup.Text> <Form.Control ref={textareaRef} style={textareaStyle} as="textarea" value={text} aria-label="Chat Input" /> </InputGroup> </Container> );}export default ChatInput;4. 注意事项与最佳实践依赖text状态:每次内容变化时调整高度。
依赖空数组[]:仅在组件挂载时执行一次(需确保DOM可用)。
类组件使用React.createRef()或回调ref。
函数组件专用useRef,更简洁。
useRef为函数组件提供了声明式的DOM访问方式,通过关联ref对象与JSX元素,结合useEffect实现高效的DOM操作。其优势包括:
合理使用useRef,可提升React应用在特定场景下的可控性与性能。