Erneutes Rendern mit React.StrictMode und der Canvas-Instanz von fabric.js
P粉659378577
P粉659378577 2023-09-21 23:48:52
0
1
724

Ich erstelle eine Stoffleinwand und Knöpfe. Die durch diese Knöpfe instanziierten Formen sollten auswählbar sein. Ich verstehe nicht, warum meine Komponente in der folgenden Situation zweimal neu gerendert wird. Daher kann meine Stoffform nicht ausgewählt werden. Wenn ich jedoch 时,渲染只发生一次,我的形状是可选择的。我可以移除 aus meiner index.tsx-Datei entferne, halte ich das nicht für die beste Lösung. Hier ist die Demo:

const { Fragment, StrictMode, useEffect, useRef } = React; const { createRoot } = ReactDOM; const styles = {}; const CanvasComponent = ({ id }) => { const canvasRef = useRef(null); useEffect(() => { console.log('init canvas'); // displayed twice with  canvasRef.current = initCanvas(); }, []); const initCanvas = () => ( canvasRef.current = new fabric.Canvas(`canvas-${id}`, { width: 800, height: 400, }) ); const addShape = (shapeType: string) => { let shape: fabric.Object; switch (shapeType) { case 'circle': shape = new fabric.Circle({ radius: 30, fill: 'red', left: 100, top: 100 }); break; case 'rectangle': shape = new fabric.Rect({ width: 60, height: 70, fill: 'green', left: 100, top: 100 }); break; default: return; } canvasRef.current.add(shape); }; return ( 
); } function StrictModeEnabled() { return

Strict Mode Enabled

; } function StrictModeDisabled() { return

Strict Mode Disabled

; } const strictModeEnabledRoot = createRoot(document.getElementById("strict-mode-enabled")); strictModeEnabledRoot.render(); const strictModeDisabledRoot = createRoot(document.getElementById("strict-mode-disabled")); strictModeDisabledRoot.render();
   

P粉659378577
P粉659378577

Antworte allen (1)
P粉850680329

问题

为什么 useEffect 在 React 中运行两次,如何处理?这个问题有很好的答案,描述了为什么会发生这种情况以及一个通用的解决方案。

解决方案

在你的情况下,你需要清理实例化的画布。我对 Fabric 不熟悉,但从阅读文档中,dispose方法似乎是合适的:

你需要从useEffect返回一个调用上述方法的函数。从链接的问题中可以看出,从useEffect返回一个进行清理的函数是一个好的实践。下面也有一个工作示例:

const { Fragment, StrictMode, useEffect, useRef } = React; const { createRoot } = ReactDOM; const styles = {}; const CanvasComponent = ({ id }) => { const canvasRef = useRef(null); useEffect(() => { console.log('init canvas'); // displayed twice with  canvasRef.current = initCanvas(); return () => canvasRef.current.dispose(); }, []); const initCanvas = () => ( canvasRef.current = new fabric.Canvas(`canvas-${id}`, { width: 800, height: 400, }) ); const addShape = (shapeType: string) => { let shape: fabric.Object; switch (shapeType) { case 'circle': shape = new fabric.Circle({ radius: 30, fill: 'red', left: 100, top: 100 }); break; case 'rectangle': shape = new fabric.Rect({ width: 60, height: 70, fill: 'green', left: 100, top: 100 }); break; default: return; } canvasRef.current.add(shape); }; return ( 
); } function StrictModeEnabled() { return

Strict Mode Enabled

; } const strictModeEnabledRoot = createRoot(document.getElementById("strict-mode-enabled")); strictModeEnabledRoot.render();
   
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!