在 React 应用中,有时需要一个文本域(
一、基本原理
二、实现步骤
1. 创建基础 React 组件
首先,我们创建一个基础的 React 组件,包含一个
import React, {useState} from 'react'; function AutoSizeTextarea() { const [text, setText] = useState(''); return ( <textarea value={text} onChange={(e) => setText(e.target.value)} /> ); } export default AutoSizeTextarea;
2. 添加自适应高度的逻辑
接下来,我们在 onChange 事件处理函数中添加逻辑以调整 textarea 的高度。
function adjustHeight(e) { e.target.style.height = 'inherit'; e.target.style.height = `${e.target.scrollHeight}px`; } function AutoSizeTextarea() { const [text, setText] = useState(''); return ( <textarea value={text} onChange={(e) => { setText(e.target.value); adjustHeight(e); }} style={{minHeight: '50px', overflow: 'hidden'}} /> ); }
在这里,我们首先将 style.height 设置为 ‘inherit’,然后立即设置为 scrollHeight 的值。scrollHeight 是元素内容的总高度,包括因溢出而不可见的部分。
3. 优化和完善
为了避免每次输入都导致不必要的渲染和高度调整,我们可以使用防抖函数来优化这个过程。
import { useDebounceFn } from 'ahooks' import React, {useState, useEffect, useRef} from 'react'; function AutoSizeTextarea() { const [text, setText] = useState(''); const textareaRef = useRef(null); const { run } = useDebounceFn( (text) => { // 调整高度,防抖控制优化 adjustHeight() }, { wait: 500, }, ) // 使用 lodash 的 debounce 函数创建一个防抖版本的 adjustHeight const adjustHeight = () => { if (textareaRef.current) { textareaRef.current.style.height = 'auto' textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px` } } return ( <textarea className="chat-input" ref={textareaRef} rows="1" autoComplete="true" placeholder="您可以输入内容向我提问" onChange={(e) => { let { value } = e.target setText(value) run(value) }} style={{minHeight: '50px', overflow: 'hidden'}} /> ); } export default AutoSizeTextarea;
在这个版本中,我们使用了 ahooks 库中的 useDebounceFn 钩子来创建一个防抖版本的 adjustHeight 函数。这样,我们就可以避免每次输入都导致不必要的渲染和高度调整。
三、结语
通过上述步骤,我们可以在 React 应用中实现一个能够根据内容自适应高度的 textarea 组件。这样的组件提高了用户界面的交互性和用户体验。
欢迎访问:天问博客