useRef - DOM Side-Effects

Gaunasi, kai norime dibrti už ReactJs (išorėja)

function MyDiv() { return ( <div ref={myDiv => { console.log(`here's my div`, myDiv) return function cleanup() { console.log(`my div is getting removed from the page`, myDiv) } }} > Hey, this is my div! </div>
  • <div> - sukurs React elementą, bet ne DOM
  • ref={()=>{}} - kai elementas bus nupieštas DOMe, React paleis šią funkciją. Kiekvieno renderinimo metu bus vykdoma šita funkcija.
function MyDiv() { const myDivRef = useRef<HTMLDivElement>(null) useEffect (() => { const myDiv = myDivRef.current // myDiv is the div DOM node! console.log(myDiv) }, []) return <div ref={myDivRef}>hi</div> }
  • useRef - gražins value
  • myDivRef.current - susietas su DOM modeliu

Pavyzdys

  • interface HTMLVanillaTiltElement extends HTML DivElement - extensina div interfeisą, nes reikia papildomo lauko
import { useState } from 'react' import { createRoot } from 'react-dom/client' import VanillaTilt from 'vanilla-tilt' interface HTMLVanillaTiltElement extends HTML DivElement { vanillaTilt?: VanillaTilt } const vanillaTiltOptions { max: 25, speed: 400, glare: true, 'max-glare': 0.5, } function Tilt({ children } { children: React. ReactNode }) { return ( <div className="tilt-root" ref={(tiltNode: HTMLVanillaTiltElement | null) => { console.log({ tiltNode }) if (!tiltNode) return VanillaTilt.init(tiltNode, vanillaTiltOptions) return () => { console.log('cleanup') tiltNode.vanillaTilt?.destroy() }} > <div className="tilt-child">{children} </div> </div>
  • if (!tiltNode) return - jeigi nėra tai graziname null
  • VanillaTilt - elementas kuris gali Leakint memmory
  • tiltNode.vanillaTilt?.destroy() cleaning

useRef ir useEffect

  • const tiltRef = useRef<HTMLVanillaTiltElement>(null) - init ref
  • if (!tiltNode) return - out iš useEfect
  • jeigu ref yra VanillaTilt.init(tiltNode, vanillaTiltOptions) init
  • useEffect (() => {},[vanillaTiltOptions]) - pasiekitus paramsas per nauja init
import { useState } from 'react' import { createRoot } from 'react-dom/client' import VanillaTilt from 'vanilla-tilt' interface HTMLVanillaTiltElement extends HTML DivElement { vanillaTilt?: VanillaTilt } const tiltRef = useRef<HTMLVanillaTiltElement>(null) const vanillaTiltOptions { max: 25, speed: 400, glare: true, 'max-glare': 0.5, } function Tilt({ children } { children: React. ReactNode }) { useEffect (() => { const { current: tiltNode } = tiltRef if (!tiltNode) return VanillaTilt.init(tiltNode, vanillaTiltOptions) return () => tiltNode.vanillaTilt?.destroy() }, [vanillaTiltOptions]) return ( <div className="tilt-root" ref={tiltRef} > <div className="tilt-child">{children} </div> </div>

Be depence kiekvien renderinimą

useEffect (() => { const { current: tilt Node } = tiltRef if (!tiltNode) return VanillaTilt.init(tiltNode, vanillaTiltOptions) return () => tiltNode.vanillaTilt?.destroy() })

tiltRef nereikie dependenco nes jis niekada nepasikeis

useEffect (() => { const { current: tilt Node } = tiltRef if (!tiltNode) return VanillaTilt.init(tiltNode, vanillaTiltOptions) return () => tiltNode.vanillaTilt?.destroy() }, [vanillaTiltOptions, tiltRef]))

React Hook useEffect has an unnecessary dependency: tiltRef.current'. Either exclude it or remove the dependency array. Mutable values like 'tiltRef.current' aren't valid dependencies because mutating them doesn't re-render the component. eslint (react-hooks/exhaustive-deps)

Esmė - mutacija be renderinimo

Kai labai daug dependence

useEffect(() => { const { current: tiltNode } = tiltRef if (!tiltNode) return const vanillaTiltOptions = { max, speed, glare, 'max-glare': maxGlare, } VanillaTilt.init(tiltNode, vanillaTiltOptions) return () => tiltNode.vanillaTilt?.destroy() }, [glare, max, maxGlare, speed])

jeigu lb dauramsu reiia onbejta neufoti arba json stringify