Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

159
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda