Je crée une toile en tissu et des boutons, les formes instanciées par ces boutons doivent être sélectionnables. Je ne comprends pas pourquoi mon composant est restitué deux fois dans la situation suivante. Par conséquent, la forme de mon tissu ne peut pas être sélectionnée. Cependant, lorsque je supprime
时,渲染只发生一次,我的形状是可选择的。我可以移除
de mon fichier index.tsx, je ne pense pas que ce soit la meilleure solution. Voici la démo :
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 withcanvasRef.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; } function StrictModeDisabled() { return Strict Mode Enabled
; } const strictModeEnabledRoot = createRoot(document.getElementById("strict-mode-enabled")); strictModeEnabledRoot.render( Strict Mode Disabled
); const strictModeDisabledRoot = createRoot(document.getElementById("strict-mode-disabled")); strictModeDisabledRoot.render( );
Question
Pourquoi useEffect s'exécute deux fois dans React et comment y faire face ?Cette question a une bonne réponse décrivant pourquoi cela se produit et une solution générale.
Solution
Dans votre cas, vous devez nettoyer le canevas instancié. Je ne connais pas Fabric, mais à la lecture de la documentation, la
dispose
méthodesemble appropriée :C'est une bonne pratique que vous deviez renvoyer une fonction de
useEffect
返回一个调用上述方法的函数。从链接的问题中可以看出,从useEffect
qui effectue le nettoyage. Vous trouverez également un exemple fonctionnel ci-dessous :