Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

152
Vistas
How to use React Hooks to update different states

I am making a background component using Vanta in NextJS, code below:

import { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import FOG from "vanta/dist/vanta.fog.min";
import { useDarkMode, useWindowSize } from "./Hooks";

const updateColor = (darkMode) => {
    return {
        highlightColor: darkMode ? 0xff0000 : 0xffd2c6,
        midtoneColor: darkMode ? 0xbe1d1d : 0xff7737,
        lowlightColor: darkMode ? 0x781212 : 0x69c3ff,
        baseColor: darkMode ? 0x0 : 0xffffff,
    }
}

export default function Background({ children }) {
    const [vantaEffect, setVantaEffect] = useState();
    //returns the width and height of the window
    const windowSize = useWindowSize();
    //user presses a button to change the theme from light to dark
    const [mode] = useDarkMode();
    const vantaRef = useRef();

    useEffect(() => {
        const isDark = mode === "dark";

        if (vantaEffect) {
            setVantaEffect(
                vantaEffect.setOptions({
                    minHeight: windowSize.height,
                    minWidth: windowSize.width,
                    ...updateColor(isDark)
                }));

            vantaEffect.resize();
        } else {
            setVantaEffect(
                FOG({
                    THREE,
                    el: vantaRef.current,
                    blurFactor: 0.18,
                    minHeight: window.innerHeight,
                    minWidth: window.innerWidth,
                    ...updateColor(isDark)
                })
            )
        }

        return () => {
            if (vantaEffect) vantaEffect.destroy();
        }
    }, [mode, windowSize]);

    return (
        <div>
            <div className="fixed -z-50" ref={vantaRef}></div>
            <div>{children}</div>
        </div>
    )
}

Right now, if either mode or windowSize is updated, the canvas will both be resized, and re-rendered for dark mode. I want to be able to detect whether it was dark mode or the window being resized ran the useEffect function.

Additionally, whenever I try to lint the function, it asks me to add vantaEffect to dependencies. When I do, the effect renders too many times and lags the page.

Is there a better way to use hooks to render the background?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

I want to be able to detect whether it was dark mode or the window being resized ran the useEffect function.

You can have two effects in your component one for mode and the other for windowSize.

Additionally, whenever I try to lint the function, it asks me to add vantaEffect to dependencies. When I do, the effect renders too many times and lags the page.

You can use functional state update to access the previous state:

useEffect(() => {
    const isDark = mode === "dark";

    setVantaEffect((previousVantaEffect) => {
       // use `previousVantaEffect` and return what you want
    })

}, [mode])
about 4 years ago · Juan Pablo Isaza Denunciar

0

To split up the mode and windowResize you should use two separate useEffect hooks. By splitting them up these hooks will only execute when the dependency is updated.

What I noticed in your code is that you execute vantaEffect.destroy() on every render. I might be mistaken, but I think that is not what you want. If you want to execute this code only on unmount you should add another useEffect without any dependencies in its array. (as stated in the React docs:

When exactly does React clean up an effect? React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time.

https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1)

The total would look something like this:

    useEffect(() => {
        const isDark = mode === "dark";

        if (vantaEffect) {
            setVantaEffect(
                vantaEffect.setOptions({
                    ...updateColor(isDark)
                }));

            vantaEffect.resize();
        } else {
            setVantaEffect(
                FOG({
                    THREE,
                    el: vantaRef.current,
                    blurFactor: 0.18,
                    minHeight: window.innerHeight,
                    minWidth: window.innerWidth,
                    ...updateColor(isDark)
                })
            )
        }
    }, [mode]);

    useEffect(() => {
        if (vantaEffect) {
            setVantaEffect(
                vantaEffect.setOptions({
                    minHeight: windowSize.height,
                    minWidth: windowSize.width
                }));

            vantaEffect.resize();
        } else {
            setVantaEffect(
                FOG({
                    THREE,
                    el: vantaRef.current,
                    blurFactor: 0.18,
                    minHeight: window.innerHeight,
                    minWidth: window.innerWidth
                })
            )
        }
    }, [windowSize]);

    useEffect(() => {
        // only destroying the vantaEffect on unmount
        return () => vantaEffect?.destroy();
    }, []);

You should optimize the output, but I hope you get the idea

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda