0

how to set intersection observer correctly. When I ask for img it only works on the last element, how to set for each element? So that they load one after another in turn

function useOnScreen(options:any){
  const ref:any = React.useRef()
  const[visible, setVisible] = React.useState(false)
useEffect(()=>{
  const observer = new IntersectionObserver(([entry])=>{
  setVisible(entry.isIntersecting)
}, options)

  if(ref.current){
    observer.observe(ref.current)
  }

  return ()=>{
      if (ref.current){
        observer.unobserve(ref.current)
      }
    } 
  },  [ref, options]) 
  return [ref, visible]
}
const [ref, visible] = useOnScreen({threshold: '0.68'})
console.log(visible,ref)
const data:any = state.data.map((item:any) => {
return (<SectionHome key={item.id}>
      ​<picture >
          <img src={item.pictures} alt={item.show_name} key={item.pictures}/>
      </picture>
      <a href={item.show_name} key={item.show_name}><p key={item.id}>{item.show_name}</p></a>
  </SectionHome>)
})
const data2:any = state.data.map((item:any) => {
  return (
    <div>
      <a href={item.show_name} key={item.show_name}>
        ​<picture ref={ref}>
        {visible ? <img src={item.pictures} alt={item.show_name} key={item.pictures}/> : <section></section>}
        </picture>
      <p key={item.id}>{item.show_name}</p></a>
    </div>  )
  })
HLEB HLEB
  • 128
  • 8

1 Answers1

0

You can create a new React Component to hold the intersection observer logic for each picture element.

// This function hook is the same.
function useOnScreen(options: any) {
  const ref: any = React.useRef()
  const [visible, setVisible] = React.useState(false)
  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setVisible(entry.isIntersecting)
    }, options)

    if (ref.current) {
      observer.observe(ref.current)
    }

    return () => {
      if (ref.current) {
        observer.unobserve(ref.current)
      }
    }
  }, [ref, options])
  return [ref, visible]
}

// This component holds the intersection observer logic and forwards all the props to the picture element.
// It accepts a function as children and the function is given whether it is visible and should return the content to render inside the picture element.
function SmartPicture(props: any) {
  const { children, ...pictureProps } = props

  const [ref, visible] = useOnScreen({ threshold: '0.68' })

  return (
    <picture {...pictureProps} ref={ref}>
      {children(visible)}
    </picture>
  )
}

// In your render function
const data: any = state.data.map((item: any) => {
  return (
    <SectionHome key={item.id}>
      <picture >
        <img src={item.pictures} alt={item.show_name} key={item.pictures} />
      </picture>
      <a href={item.show_name} key={item.show_name}><p key={item.id}>{item.show_name}</p></a>
    </SectionHome>
  )
})

const data2: any = state.data.map((item: any) => {
  return (
    <div>
      <a href={item.show_name} key={item.show_name}>
        <SmartPicture>
          {(visible) => visible ? <img src={item.pictures} alt={item.show_name} key={item.pictures} /> : <section></section>}
        </SmartPicture>
        <p key={item.id}>{item.show_name}</p></a>
    </div>
  )
})
Alvin Leung
  • 668
  • 1
  • 5
  • 10