React测试时useEffect设置textarea rows触发IndexSizeError如何解决
问题原因
- 测试环境默认使用
jsdom作为DOM模拟环境,不会真实渲染元素计算布局属性,哪怕你最终得到的rows赋值为1符合预期,部分版本的jsdom在textarea尚未完成挂载流程时设置rows属性,会抛出IndexSizeError异常 - 你当前的交互代码写法有误:
@testing-library/user-eventv14及以上所有交互方法均为异步方法,你未加await且手动包裹了不必要的act,导致组件状态更新时序异常,useEffect触发时DOM还未完全就绪 - 生产环境为真实浏览器,元素布局计算、挂载时序都符合预期,因此不会触发报错
解决方法
方案1:修复测试侧交互写法
优先修正userEvent的调用方式,不需要手动包裹act,React Testing Library会自动处理状态更新的act包裹:
// 如果你用的是userEvent v13及以下版本 - act(() => { - userEvent.click(addProblemButton); - }); + await userEvent.click(addProblemButton); // 如果你用的是userEvent v14及以上版本,需要先初始化实例 const user = userEvent.setup() // 后续交互调用 await user.click(addProblemButton)
方案2:兼容jsdom环境的高度计算逻辑
给textarea的高度计算逻辑加边界兜底,避免异常值导致报错:
useEffect(() => { if (textAreaRef.current) { + // 兜底scrollHeight异常值,取最小行数对应的高度作为默认值 + const scrollHeight = textAreaRef.current.scrollHeight || fontSize * minRows const currentRows = Math.ceil( - textAreaRef.current.scrollHeight / fontSize - 1 + scrollHeight / fontSize - 1 ); + // 确保计算结果为合法正整数 + const safeRows = Number.isInteger(currentRows) && currentRows > 0 ? currentRows : minRows textAreaRef.current.rows = minMax(safeRows, minRows, maxRows); } }, [minRows, maxRows]);
方案3:测试侧Mock自动高度逻辑(可选)
如果你的测试用例不需要验证textarea的自动高度功能,可以直接在测试文件中Mock TextArea组件,跳过高度计算逻辑:
jest.mock('你的TextArea组件路径', () => { const originalModule = jest.requireActual('你的TextArea组件路径') return { ...originalModule, default: (props) => <textarea {...props} /> } })
内容的提问来源于stack exchange,提问作者mTv
相关产品推荐
相关产品推荐

