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.

Problema del interruptor toggle en el gancho useEffect de React.

Me confundí con cómo funciona useEffect en React. El siguiente código funciona, pero de manera opuesta a lo que se pretende. En lugar de que la imagen de fondo aparezca después de marcar la casilla de verificación, aparece cuando la casilla no está marcada y desaparece cuando está marcada.

function Beautifier() {
  const [isBeautiful, setIsBeautiful] = React.useState(false);

  React.useEffect(
    function toggleBackground(shouldShow) {
      document.body.classList.toggle('with-bg', shouldShow);
    }
  );

  function handleChange() {
    setIsBeautiful(!isBeautiful);
  }

  return (
    <label>
      <input type="checkbox" onchange="{handleChange}">
      Activar bonito fondo
    </label>
  );
}

ReactDOM.render((
  <beautifier></beautifier>
), document.querySelector('#root'));

Estoy bastante seguro de que mi problema es que me falta un return () => en el gancho de useEffect, pero todas las cosas que se me ocurren no resuelven el problema o rompen la función. No agrego CSS, ya que esa parte funciona bien.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para solucionar el problema, debes agregar una declaración de retorno en el hook useEffect que tome una función como argumento. Esta función se ejecutará cuando el componente se desmonte.

    Aquí está el código corregido:

    function Beautifier() {
      const [isBeautiful, setIsBeautiful] = React.useState(false);
    
      React.useEffect(
        function toggleBackground() {
          document.body.classList.toggle('with-bg', isBeautiful);
          return () => {
            document.body.classList.remove('with-bg');
          }
        }, [isBeautiful]
      );
    
      function handleChange() {
        setIsBeautiful(!isBeautiful);
      } 
    
      return (
        <label>
          <input type="checkbox" onchange="{handleChange}">
          Activar fondo bonito
        </label>
      );
    }
    
    ReactDOM.render((
      <beautifier></beautifier>
    ), document.querySelector('#root'));
    

    Aquí, pasamos [isBeautiful] como segundo argumento a useEffect para que el efecto se ejecute solo cuando isBeautiful cambie. También agregamos una declaración de retorno que elimina la clase with-bg del cuerpo cuando el componente se desmonta. Esto debería solucionar el problema de que la imagen de fondo aparezca cuando la casilla no está marcada.

Comments are closed.