es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo inicializo una variable sin inicializarla en cada rerenderizado?

Creo que estoy perdido… no puedo entender este problema.

¿Cómo puedo inicializar la variable “cssCompiler” en el componente “CodePreview” sin inicializarla en cada renderizado? Si lo coloco en un useEffect, estoy violando las reglas del React Hook.

CodePreview

import SassCompiler from './compiler/sass_compiler';
const CodePreview = ({ codeContent, saveSnippet }) => {
    // Inicializar con valores predeterminados
    const [css, setCss] = useState(codeContent.CSS.code);
    const cssCompiler = useRef(null);

    if (codeContent.CSS.mode === 'sass') {
        cssCompiler.current = sass_compiler(css, setCss);
        console.log('Compiler: ', cssCompiler);
    }

    useEffect(() => {
        if (cssCompiler.current) {
            cssCompiler.current.compileSass(codeContent.CSS.code)
        }
    }, [css])
    ...
}

SassCompiler

import useScript from "../../../../hooks/useScript";
import { useRef } from 'react';
const SassCompiler = (css, setCss) => {
    const compiler = useRef(null);
    useScript('js/libs/sass.js/dist/sass.js', () => {
        compiler.current = new window.Sass();
        compileSass(css)
        console.log('SASS Compiler setted');
    });

    const compileSass = (sass) => {
        try {
            compiler.current.compile(sass, (result) => {
                setCss(result.text);
                console.log('SASS Compiled');
            });
        } catch (e) {
            console.log('Err: ', e);
        }
    }
}

export default SassCompiler;

useScript.js

import { useEffect } from 'react';

const useScript = (url, onLoad) => {
    useEffect(() => {
        const script = document.createElement('script');
        script.src = url;
        script.async = true;
        document.body.appendChild(script);
        if (onLoad) script.onload = () => onLoad();

        return () => {
            document.body.removeChild(script);
        }
    }, [url]);
};

export default useScript;
Tags:  ,

Answer

  1. Avatar for davy.ai

    Para inicializar la variable “cssCompiler” en el componente CodePreview sin inicializarla en cada rerenderizado, puedes usar el hook “useMemo”. “useMemo” te permite memoizar un valor para que solo se recalcule cuando cambien sus dependencias. En este caso, las dependencias serían la propiedad “mode” del objeto “codeContent.CSS”.

    Aquí tienes un ejemplo de cómo puedes usar “useMemo” en el componente CodePreview:

    import SassCompiler from './compiler/sass_compiler';
    
    const CodePreview = ({ codeContent, saveSnippet }) => {
      // Inicializar con valores predeterminados
      const [css, setCss] = useState(codeContent.CSS.code);
    
      const cssCompiler = useMemo(() => {
        if (codeContent.CSS.mode === 'sass') {
          return new SassCompiler(css, setCss);
        }
        return null;
      }, [css, codeContent.CSS.mode]);
    
      useEffect(() => {
        if (cssCompiler) {
          cssCompiler.compileSass(codeContent.CSS.code);
        }
      }, [css, cssCompiler, codeContent.CSS.code]);
    
      // ...
    }
    

    En este código, la variable “cssCompiler” se inicializa utilizando una llamada a “useMemo”. Si la propiedad “mode” del objeto “codeContent.CSS” es “sass”, se crea y devuelve una nueva instancia de la clase “SassCompiler”. De lo contrario, se devuelve “null”. Las dependencias del valor memoizado son “css” y “codeContent.CSS.mode”.

    Al usar “useMemo”, la variable “cssCompiler” solo se inicializará cuando cambien sus dependencias. Esto garantiza que no se inicialice cada vez que el componente se vuelva a renderizar, lo cual violaría las reglas de React Hooks.

Comments are closed.