useEffectWithTarget
A hook to create an effect with a target element that re-runs when the target or dependencies change
Installation
npx shadcn@latest add @shadcnhooks/use-effect-with-targetUsage
useEffectWithTarget is similar to useEffect, but it accepts a target parameter. The effect will re-run when either the dependencies or the target element changes.
Basic Usage
import { useEffectWithTarget } from '@/hooks/use-effect-with-target'
import { useRef } from 'react'
function MyComponent() {
const divRef = useRef<HTMLDivElement>(null)
useEffectWithTarget(
() => {
const element = divRef.current
if (element) {
// Do something with the element
console.log('Element mounted:', element)
}
return () => {
// Cleanup
console.log('Element unmounted')
}
},
[],
divRef,
)
return <div ref={divRef}>Hello</div>
}With DOM Element
import { useEffectWithTarget } from '@/hooks/use-effect-with-target'
function MyComponent() {
const element = document.getElementById('my-element')
useEffectWithTarget(
() => {
if (element) {
// Do something with the element
}
},
[],
element,
)
return <div id='my-element'>Hello</div>
}With Function Target
import { useEffectWithTarget } from '@/hooks/use-effect-with-target'
function MyComponent() {
useEffectWithTarget(
() => {
const element = document.querySelector('.my-class')
if (element) {
// Do something with the element
}
},
[],
() => document.querySelector('.my-class'),
)
return <div className='my-class'>Hello</div>
}With Multiple Targets
import { useEffectWithTarget } from '@/hooks/use-effect-with-target'
import { useRef } from 'react'
function MyComponent() {
const ref1 = useRef<HTMLDivElement>(null)
const ref2 = useRef<HTMLDivElement>(null)
useEffectWithTarget(
() => {
// Effect runs when either ref1 or ref2 changes
console.log('Targets changed')
},
[],
[ref1, ref2],
)
return (
<>
<div ref={ref1}>First</div>
<div ref={ref2}>Second</div>
</>
)
}With Dependencies
import { useEffectWithTarget } from '@/hooks/use-effect-with-target'
import { useRef, useState } from 'react'
function MyComponent() {
const [count, setCount] = useState(0)
const divRef = useRef<HTMLDivElement>(null)
useEffectWithTarget(
() => {
// Effect runs when count changes or when divRef.current changes
console.log('Count:', count)
},
[count],
divRef,
)
return (
<div ref={divRef}>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}API
type TargetValue<T> = T | undefined | null
type TargetType = HTMLElement | Element | Window | Document
type BasicTarget<T extends TargetType = Element> =
(() => TargetValue<T>) | TargetValue<T> | RefObject<TargetValue<T>>
/**
* A hook to create an effect with a target element
* @param effect - The effect callback function
* @param deps - The dependency array (same as useEffect)
* @param target - The target element(s). Can be a DOM element, ref object, function that returns an element, or an array of these
* @returns void
*/
export const useEffectWithTarget: (
effect: EffectCallback,
deps: DependencyList,
target: BasicTarget<any> | BasicTarget<any>[],
) => voidCredits
Last updated on