React中出现Uncaught RangeError: Maximum call stack size exceeded问题求助
解决React中
Maximum call stack size exceeded错误 错误原因分析
当你滑动滑块更新zoom状态时,组件会触发重渲染。此时代码直接在JSX里计算图片的base64地址:
src={`data:image/${tree.image.contentType};base64,${btoa(String.fromCharCode(...new Uint8Array(tree.image.data.data)))}`}
如果tree.image.data.data是较大的数组,...new Uint8Array(tree.image.data.data)会将数组展开为大量参数传递给String.fromCharCode,超过JavaScript函数调用的参数数量上限,直接导致调用栈溢出。每次重渲染都会重复执行这个高开销的转换操作,最终触发错误。
另一个组件能正常工作,大概率是因为它处理的图片数据量较小,展开后的参数数量未达到阈值。
修复方案
将图片base64的转换逻辑从渲染阶段移到数据获取完成后的副作用中,只执行一次并缓存结果:
- 添加一个新状态存储转换后的图片地址:
const [imageSrc, setImageSrc] = useState("")
- 在获取树数据的
useEffect中完成base64转换并更新状态:
useEffect(() => { console.log("id", id) apiService.getOne(id).then(t => { console.log("data", t) // 一次性完成图片base64转换 const byteArray = new Uint8Array(t.image.data.data) const base64Str = btoa(String.fromCharCode(...byteArray)) const src = `data:image/${t.image.contentType};base64,${base64Str}` setImageSrc(src) setTree(t) setLocation({latitude: t.location.latitude, longitude: t.location.longitude}) setFetching(false) }) }, [id]) // 加入id作为依赖,确保路由参数变化时重新获取数据
- 在JSX中直接使用缓存好的
imageSrc:
{ fetching === false ? <img style={{height: '200px', width: '300px'}} src={imageSrc} alt='Tree image' /> : <Spinner animation="border" variant="primary" /> }
额外优化点
- 原代码中
useEffect的依赖数组为空,当路由参数id变化时不会重新获取数据,加入id作为依赖可以修复这个潜在问题。 - 为图片添加有意义的
alt文本,提升可访问性。
内容的提问来源于stack exchange,提问作者Daniel Nikkari
相关产品推荐
相关产品推荐

