i have a function calculateDistance
which calculate when the child component is in the center of the parent component. I want to fire the function on the onScroll
event. But the variables I need for it a set in a useEffect and cannot use outside that scope. Has anyone an idea how to fix this?
export function Portfolio() {
const portfolioRef = React.useRef(null)
React.useEffect(() => {
portfolioRef.current.scrollTop = 100
}, []
)
return (
<div className={cx(styles.component, styles.scrollWrapper)}>
<div className={styles.topIcon} dangerouslySetInnerHTML={{ __html: arrow }} />
<div ref={portfolioRef} onScroll={calculateDistance} className={styles.scroll}>
<PortfolioItem
{...{ portfolioRef }}
title='Article about Kaliber Academie'
text='I wrote an article about my experience at Kaliber'
link='https://medium.com/kaliberinteractive/hoe-technologie-het-hart-van-een-luie-scholier-veranderde-3cd3795c6e33'
linkTekst='See Article' />
<PortfolioItem
{...{ portfolioRef }}
title='Article about Kaliber Academie'
text='hola'
link='#'
linkTekst='#' />
<PortfolioItem
{...{ portfolioRef }}
title='Article about Kaliber Academie'
text='hola'
link='#'
linkTekst='#' />
<PortfolioItem
{...{ portfolioRef }}
title='Article about Kaliber Academie'
text='hola'
link='#'
linkTekst='#' />
</div>
<div className={styles.bottomIcon} dangerouslySetInnerHTML={{ __html: arrow }} />
</div>
)
}
export function PortfolioItem({ text, title, link, linkTekst, portfolioRef }) {
const portfolioItemRef = React.useRef(null)
React.useEffect(() => {
const element = portfolioItemRef.current
const parent = portfolioRef.current
}, [portfolioRef])
return (
<div ref={portfolioItemRef} className={styles.componentItem}>
<div className={styles.title}>{title}</div>
<div className={styles.content}>
<div className={styles.text}>{text}</div>
<div className={styles.links}>
<a className={styles.linkTekst} href={link}>{linkTekst} </a>
<div className={styles.linkIcon} dangerouslySetInnerHTML={{ __html:arrow }} />
</div>
</div>
</div>
)
}
function calculateDistance(parent, element) {
if (!parent || !element) return 0
const parentRect = parent.getBoundingClientRect()
const parentCenter = (parentRect.top + parentRect.bottom) / 2
const elementRect = element.getBoundingClientRect()
const elementCenter = (elementRect.top + elementRect.bottom) / 2
const distance = Math.abs(parentCenter - elementCenter)
return clamp(distance / (parentRect.height / 2), 0, 1)
}
It doesnt look as if your calculated distance is being stored anywhere. You probably want the calulateDistance function to update a state variable which you refer to in Portfolio's useEffect.
You can create new variables from your component props and use useState()
. you can then update them and reference them in your jsx and changing them will trigger your useEffect()
, as long as you have it bounded correctly. Using props directly will only trigger your unbounded useEffect on the initial load. Additionally the reference you made 'portfolioItemRef' is only set when rendered and using it as the bound for the useEffect will not update to the calculated distance as is. move the calculated distance function into the portfolio component.
For Example:
const [stateText, setStateText] = useState(text)
useEffect(()=>{console.log('do something')},[stateText]);
here is a helpful explanation: https://medium.com/better-programming/tips-for-using-reacts-useeffect-effectively-dfe6ae951421
Best thing you can do is listen for the scroll event inside the useEffect
remove the onScroll
attached to element
....
<div ref={portfolioRef} className={styles.scroll}>
....
inside useEffect
React.useEffect(() => {
const calculateDistance = (parent, element) => {
if (!parent || !element) return 0
const parentRect = parent.getBoundingClientRect()
const parentCenter = (parentRect.top + parentRect.bottom) / 2
const elementRect = element.getBoundingClientRect()
const elementCenter = (elementRect.top + elementRect.bottom) / 2
const distance = Math.abs(parentCenter - elementCenter)
return clamp(distance / (parentRect.height / 2), 0, 1)
}
//attach event listener
portfolioRef.current.addEventListener("scroll", calculateDistance);
return () => {
// remove the event listener when component unmounts
portfolioRef.current.removeEventListener("scroll", calculateDistance);
}
}, [])
you have to decide how to get the parent
and element
inside the calculateDistance
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.