簡體   English   中英

在 useEffect 中設置變量時如何觸發 function?

[英]How to fire function when the variables are set in a useEffect?

我有一個 function calculateDistance計算子組件何時位於父組件的中心。 我想在onScroll事件上觸發 function。 但是我需要的變量在useEffect中設置並且不能在scope之外使用。 有誰知道如何解決這個問題?

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)
}

看起來您計算的距離似乎沒有存儲在任何地方。 您可能希望 calulateDistance function 更新您在投資組合的 useEffect 中引用的 state 變量。

您可以從組件道具創建新變量並使用useState() 然后,您可以更新它們並在您的 jsx 中引用它們並更改它們將觸發您的useEffect() ,只要您的邊界正確。 直接使用道具只會在初始加載時觸發您的無限 useEffect。 此外,您所做的“portfolioItemRef”引用僅在渲染時設置,並將其用作 useEffect 的界限不會按原樣更新為計算的距離。 將計算出的距離 function 移動到投資組合組件中。

例如:

const [stateText, setStateText] = useState(text)
useEffect(()=>{console.log('do something')},[stateText]);

這是一個有用的解釋: https://medium.com/better-programming/tips-for-using-reacts-useeffect-effectively-dfe6ae951421

您可以做的最好的事情是監聽useEffect中的滾動事件

移除附加到元素的onScroll

....
<div ref={portfolioRef} className={styles.scroll}>
....

內部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);
    }
}, [])

演示

您必須決定如何在calculateDistance中獲取parent元素和element

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM