TextArea初始为1行时无法正确自动调整高度问题求助
解决TextArea自动扩展高度的2行显示异常及初始高度固定问题
问题根源分析
- 垂直居中导致显示异常:你的
InputWrapper设置了align-items: center,当文本内容变为2行时,textarea会被垂直居中,视觉上出现显示异常;1行时居中效果不明显,3行及以上因高度超过容器默认高度,居中效果被覆盖,所以表现正常。 - Ref管理冗余:用
useState存储React.createRef()会触发不必要的状态更新,ref本身是可变引用,无需存入state。 - 初始高度计算不精确:要保证初始总高度40px,需要结合容器padding和textarea的高度做精确计算。
解决方案代码
import React, { useRef, useEffect } from "react"; import styled from "styled-components"; const InputWrapper = styled.div` display: inline-flex; justify-content: flex-start; align-items: flex-start; /* 改为flex-start,让textarea从顶部开始排列 */ width: 100%; padding: 8px 16px; border-radius: 6px; background-color: white; border: 1px solid black; box-sizing: border-box; /* 确保padding计入总高度 */ min-height: 40px; /* 固定初始总高度 */ `; const StyledTextArea = styled.textarea` width: 100%; max-height: 300px; font-size: 16px; background-color: white; line-height: 18px; resize: none; transition: all 300ms; border: none; overflow: hidden; min-height: 24px; /* 40px总高度 - 上下padding(8*2) = 24px */ padding: 0; /* 去掉默认内边距,避免高度计算偏差 */ margin: 0; `; const TextArea = ({ value, placeholder, handleEvent }) => { const textAreaRef = useRef(null); // 用useRef替代useState存储引用 const updateHeight = () => { if (!textAreaRef.current) return; // 先重置为最小高度,再计算scrollHeight textAreaRef.current.style.height = `${StyledTextArea.minHeight}`; const scrollHeight = textAreaRef.current.scrollHeight; textAreaRef.current.style.height = `${scrollHeight}px`; }; useEffect(() => { updateHeight(); // 监听窗口resize,避免宽度变化导致高度异常 window.addEventListener('resize', updateHeight); return () => window.removeEventListener('resize', updateHeight); }, [value]); return ( <InputWrapper> <StyledTextArea ref={textAreaRef} value={value} rows={1} placeholder={placeholder} onChange={handleEvent} /> </InputWrapper> ); }; export default TextArea;
关键修改说明
InputWrapper的align-items: flex-start:让textarea从容器顶部开始排列,无论行数多少,文本都能正常显示,直接解决2行时的垂直居中异常。- 固定初始总高度:给
InputWrapper设置min-height: 40px,同时计算textarea的min-height为40px - 8px*2 = 24px,确保初始状态总高度完全符合要求。 useRef替代useState:ref是可变引用,直接用useRef存储无需触发状态更新,简化逻辑且避免不必要的重渲染。- 优化高度计算逻辑:重置高度时先设为
min-height,再基于scrollHeight设置实际高度,避免浏览器默认的rows高度干扰计算,确保1-3行及以上都能正常扩展。 - 添加resize监听:窗口宽度变化时重新计算高度,避免文本换行后高度不匹配的问题。
内容的提问来源于stack exchange,提问作者J4v4Scr1pt
相关产品推荐
相关产品推荐

