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

React实现textarea自动增长后无法自动收缩如何解决

Textarea高度双向自适应修复方案

你现有代码仅能增高无法收缩的核心原因有三点:

  • 高度重置逻辑兼容性差,设为0px的方式在部分场景下无法让浏览器正确计算收缩后的内容高度
  • 仅在用户输入时触发高度计算,组件初始挂载、外部赋值/清空内容时不会执行自适应逻辑
  • 组件接收的className参数未合并到渲染节点,易出现自定义样式失效导致的高度计算偏差

修正后的样式代码

保留原有基础样式,可按需配置最小高度避免空内容时高度塌缩,也可添加最大高度限制:

.textarea {
  resize: none;
  overflow: hidden;
  box-sizing: border-box;
  /* 按需自定义最小高度 */
  min-height: 40px;
  /* 按需自定义最大高度,超出后显示滚动条 */
  /* max-height: 200px; */
}

修正后的组件实现

引入Ref实例绑定textarea节点,封装独立的自适应方法,覆盖所有触发高度变化的场景:

import { useRef, useEffect, useCallback } from 'react'
// 按你的项目实际路径导入样式文件
import styles from './textarea.module.css'

export default function Textarea({
  className,
  onChange,
  defaultValue,
  value,
  ...attrs
}) {
  const textareaRef = useRef(null)

  // 封装高度自适应逻辑
  const adjustHeight = useCallback(() => {
    const el = textareaRef.current
    if (!el) return
    // 先重置高度为auto,触发浏览器重排收回多余高度
    el.style.height = 'auto'
    // 赋值为内容实际高度,完成自适应
    el.style.height = `${el.scrollHeight}px`
  }, [])

  // 组件挂载、受控值/默认值变更时自动调整高度
  useEffect(() => {
    adjustHeight()
  }, [value, defaultValue, adjustHeight])

  const handleInput = (e) => {
    adjustHeight()
    onChange?.(e)
  }

  return (
    <textarea
      {...attrs}
      ref={textareaRef}
      value={value}
      defaultValue={defaultValue}
      onInput={handleInput}
      // 合并内置样式与外部传入的自定义类名
      className={`${styles.textarea} ${className ?? ''}`.trim()}
    />
  )
}

关键逻辑说明

  • 高度重置阶段使用height: auto替代原来的height: 0px,兼容性更好,不会因为高度骤降触发页面滚动条跳动,同时能保证内容减少时浏览器可以正确计算收缩后的基准高度
  • 自适应逻辑同时覆盖了用户输入、初始渲染、外部赋值/清空内容三类场景,不会出现内容变了高度没更新的问题
  • 样式类名合并逻辑保证外部自定义的padding、border、min-height等样式可以正常生效,不会干扰高度计算

内容的提问来源于stack exchange,提问作者Lance Pollard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:51:28