我正在使用NextJS 中的Vanta制作背景組件,代碼如下:
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>
)
}
現在,如果更新 mode 或 windowSize,畫布都將調整大小,并重新渲染為暗模式。我希望能夠檢測它是暗模式還是正在調整大小的視窗運行了 useEffect 函式。
此外,每當我嘗試對函式進行 lint 處理時,它都會要求我將vantaEffect 添加到依賴項中。當我這樣做時,效果呈現太多次并滯后于頁面。
有沒有更好的方法使用鉤子來渲染背景?
uj5u.com熱心網友回復:
要拆分mode,windowResize您應該使用兩個單獨的useEffect鉤子。通過將它們分開,這些鉤子只會在更新依賴項時執行。
我在您的代碼中注意到您vantaEffect.destroy()在每次渲染時執行。我可能錯了,但我認為這不是你想要的。如果您只想在其上執行此代碼,unmount則應useEffect在其陣列中添加另一個沒有任何依賴項的代碼。(如 React 檔案中所述:
React 什么時候清理效果?當組件卸載時,React 執行清理。但是,正如我們之前所了解的,效果會在每次渲染時運行,而不僅僅是一次。這就是為什么 React還會在下次運行效果之前清除上一次渲染中的效果。
https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1 )
總數看起來像這樣:
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();
}, []);
你應該優化輸出,但我希望你能明白
uj5u.com熱心網友回復:
我希望能夠檢測它是暗模式還是正在調整大小的視窗運行了 useEffect 函式。
您的組件中可以有兩種效果,一種是 for mode,另一種是for windowSize。
此外,每當我嘗試對函式進行 lint 處理時,它都會要求我將vantaEffect 添加到依賴項中。當我這樣做時,效果呈現太多次并滯后于頁面。
您可以使用功能狀態更新來訪問以前的狀態:
useEffect(() => {
const isDark = mode === "dark";
setVantaEffect((previousVantaEffect) => {
// use `previousVantaEffect` and return what you want
})
}, [mode])
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/381586.html
標籤:javascript 反应 反应钩子 下一个.js
上一篇:for回圈神秘地沒有運行
