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

React切换textarea模式后blobRef为null:高度自适应异常求助

问题原因及解决方案

为什么切换模式后blobRef变成null?

React的状态更新是异步的。在toggleChecklist函数中,调用setChecklist((prev) => !prev)后,checklist的新值不会立刻生效——此时执行if (checklist)代码块时,checklist还是切换前的旧值(也就是当前处于checklist模式,值为true)。

这时候组件还没完成重新渲染,单个textarea还没被挂载到DOM上,blobRef自然还没被赋值,所以blobRef.current是null。只有当组件重新渲染完成,checklist变为false,dataArea()返回的单个textarea才会被渲染,blobRef才会指向对应的DOM元素。


解决方案

方案1:用useEffect监听状态变化,在组件渲染完成后操作

把原来toggleChecklist里操作blobRef的逻辑,移到监听checklist状态的useEffect中,确保组件已经重新渲染、单个textarea挂载完成后再执行:

import { useEffect, useRef, useState } from 'react';

// ... 其他代码

const blobRef = useRef(null);

// 新增useEffect监听checklist状态
useEffect(() => {
  // 当从checklist模式切换到单个textarea模式时
  if (!checklist) {
    // 此时textarea已挂载,blobRef.current可用
    blobRef.current?.dispatchEvent(new Event('input'));
  }
}, [checklist]);

function toggleChecklist() {
  setChecklist((prevChecklist) => !prevChecklist);
  if (checklist) {
    const n = '\n'; // 直接用换行符更简洁
    setData(checklistData.reduce((p, c) => p.concat(c.data + n), ''));
    // 移除这里的blobRef操作
  }
}

// ... 其他代码

方案2:抽离高度调整逻辑,避免依赖input事件

把自动增高的逻辑抽成独立函数,无论是用户输入还是状态更新后,都可以直接调用,更可靠:

function adjustTextareaHeight(element) {
  if (!element) return;
  element.style.height = '0';
  element.style.height = element.scrollHeight + 'px';
}

// 在handleInput中调用
function handleInput(e, i) {
  const element = e.target;
  // ... 原有的状态更新逻辑
  adjustTextareaHeight(element);
}

// 在useEffect中调用,处理状态更新后的高度调整
useEffect(() => {
  if (!checklist) {
    adjustTextareaHeight(blobRef.current);
  }
}, [checklist, data]); // 监听data变化,确保合并后的内容能触发高度调整

这样即使不手动触发input事件,也能保证textarea的高度自动适配内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:54:22