You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TextArea初始为1行时无法正确自动调整高度问题求助

解决TextArea自动扩展高度的2行显示异常及初始高度固定问题

问题根源分析

  1. 垂直居中导致显示异常:你的InputWrapper设置了align-items: center,当文本内容变为2行时,textarea会被垂直居中,视觉上出现显示异常;1行时居中效果不明显,3行及以上因高度超过容器默认高度,居中效果被覆盖,所以表现正常。
  2. Ref管理冗余:用useState存储React.createRef()会触发不必要的状态更新,ref本身是可变引用,无需存入state。
  3. 初始高度计算不精确:要保证初始总高度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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:10:31