-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[useIntersectionObserver] Introduce new API #16663
Comments
@pranshuchittora Could you develop why Material-UI should solve this problem? Would it be better handled in a generic hook library? For instance https://github.com/thebuilder/react-intersection-observer? In the past, I have used this implementation (before hooks were available): import React from 'react'
import PropTypes from 'prop-types'
import waitUntil from 'modules/async/waitUntil'
class IntersectionObserver extends React.Component {
state = {
visible: this.props.defaultVisible,
}
async componentDidMount() {
if (this.props.defaultVisible) {
return
}
await waitUntil(() => ({ predicate: Boolean(window.IntersectionObserver) }), {
delay: 300,
tries: 10,
})
this.io = new window.IntersectionObserver(entries => {
const entry = entries[0]
if (this.state.visible !== entry.isIntersecting && entry.isIntersecting === true) {
this.setState({ visible: entry.isIntersecting })
this.io.disconnect()
}
}, this.props.options)
this.io.observe(this.container)
}
componentWillUnmount() {
if (this.io) {
this.io.disconnect()
}
}
handleRef = ref => {
this.container = ref
}
render() {
const { children, defaultVisible, options, ...other } = this.props
return (
<div ref={this.handleRef} {...other}>
{children({ visible: this.state.visible })}
</div>
)
}
}
IntersectionObserver.propTypes = {
children: PropTypes.func.isRequired,
defaultVisible: PropTypes.bool,
options: PropTypes.object,
}
IntersectionObserver.defaultProps = {
defaultVisible: false,
}
IntersectionObserver.displayName = 'IntersectionObserver'
export default IntersectionObserver Usage: <IntersectionObserver
defaultVisible={listIndex < 25}
options={{
rootMargin: '0px 0px 400px 0px',
}}
>
{({ visible }) => (
<img
alt={getAlt(image)}
height={height}
width={width}
className={classes.img}
src={visible ? image.url.small : searchEmpty}
data-e2e="gallery.image.imgTag"
/>
)}
</IntersectionObserver> Polyfill for Safari and IE: <script
defer
src="https://polyfill.io/v3/polyfill.min.js?flags=gated&features=IntersectionObserver&unknown=polyfill"
/> |
I have added the |
Sorry for the late reply. I know that this can be implemented using a third-party package, but this requires a lot of boilerplate code. Apart from that, there might be some performance issue(maybe). If there's a native implementation in the MUI. Then it opens a room for an awesome fast components like.
|
To further expand on my reasoning.we can compare the usage rate between the generic API https://github.com/thebuilder/react-intersection-observer and the specialized one: https://github.com/jasonslyvia/react-lazyload, https://github.com/bvaughn/react-virtualized. There is a x10 difference. I believe working on this would be a distraction for us. In the future, I think that it would be great to explore the potential of an image component for Material-UI. Maybe something that comes with display transition, lazyload, error handling. Not a priority either, but I'm wondering about the potential 🤔. |
IMHO if you decide on using a generic library (e.g. |
Hey, @oliviertassinari glad to see this happening. |
With only one upvote in 18 months, this can be closed. |
Note: This proposal is in its very early stage.
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
Expected Behavior 🤔
Implementation should somewhat look like
useScrollTrigger
Current Behavior 😯
User implemented
Examples 🌈
Context 🔦
Benchmark
The text was updated successfully, but these errors were encountered: