如何在条件渲染的子组件中正确使用useEffect生成SVG
问题解决代码及说明
错误原因
直接调用SVGpaper()函数而非以<SVGpaper />组件形式渲染,违反了React Hooks的调用规则——Hooks必须在React组件的顶层调用,直接函数调用会让React无法正确追踪Hooks的执行顺序,从而触发报错。
修改后的完整代码
import { useEffect, useRef } from 'react'; import { SVG } from '@svgdotjs/svg.js'; const SVGpaper = () => { // 使用ref获取canvas DOM元素,替代全局id const canvasRef = useRef(null); useEffect(() => { // 确保ref已关联到DOM元素 if (!canvasRef.current) return; // 创建SVG实例并绑定到ref指向的div const svgInstance = SVG().addTo(canvasRef.current).size(600, 600); svgInstance.rect(100, 100); // 组件卸载时清理SVG实例,避免内存泄漏 return () => { svgInstance.remove(); }; }, []); // 空依赖数组确保只在组件挂载时执行一次 return <div ref={canvasRef}></div>; }; const Profile = ({ someVariable }) => { return ( someVariable && ( <CCol> <CRow> <div> {/* 以React组件形式渲染,而非直接调用函数 */} <SVGpaper /> </div> </CRow> </CCol> ) ); }; export default Profile;
关键修改点
- 组件渲染方式:将
{SVGpaper()}改为<SVGpaper />,让React正确识别组件并管理其中的Hooks。 - DOM元素获取:用
useRef替代id="canvas",避免全局id冲突,同时更安全地获取DOM节点。 - useEffect优化:添加空依赖数组
[],确保SVG初始化逻辑仅在组件挂载时执行一次;增加清理函数,在组件卸载时移除SVG实例,防止内存泄漏。 - 条件渲染简化:直接用
someVariable && ...替代typeof someVariable !== "undefined",逻辑更简洁(若someVariable可能为布尔假值如0、""等,可保留原判断逻辑)。
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

