Releases: thebuilder/react-intersection-observer
Testing utils
This releases is focused on helping you when writing tests.
In order to write meaningful tests, the IntersectionObserver
needs to be
mocked. If you are writing your tests in Jest, you can use the included
test-utils.js
. It mocks the IntersectionObserver
, and includes a few methods
to assist with faking the inView
state.
test-utils.js
Import the methods from react-intersection-observer/test-utils
.
mockAllIsIntersecting(isIntersecting:boolean)
Set the isIntersecting
on all current IntersectionObserver instances.
mockIsIntersecting(element:Element, isIntersecting:boolean)
Set the isIntersecting
for the IntersectionObserver of a specific element.
intersectionMockInstance(element:Element): IntersectionObserver
Call the intersectionMockInstance
method with an element, to get the (mocked)
IntersectionObserver
instance. You can use this to spy on the observe
and
unobserve
methods.
Test Example
import React from 'react'
import { render } from 'react-testing-library'
import { useInView } from 'react-intersection-observer'
import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils'
const HookComponent = ({ options }) => {
const [ref, inView] = useInView(options)
return <div ref={ref}>{inView.toString()}</div>
}
test('should create a hook inView', () => {
const { getByText } = render(<HookComponent />)
mockAllIsIntersecting(true)
getByText('true')
})
Rewritten Hooks and tests
So now that Hooks have been out in the wild for a week, a few issues are starting to pop up.
Especially relating to how refs are handled (#162). To fix this, the current API needs to be changed.
New useInView
API:
const [ref, inView, entry] = useInView(options)
If you are already using the hook, then you will need to update your code, by changing:
const Component = () => {
const ref = useRef()
const inView = useInView(ref, {
threshold: 0,
})
return (
<div ref={ref}>
...
</div>
)
}
Into:
const Component = () => {
const [ref, inView] = useInView({
threshold: 0,
})
return (
<div ref={ref}>
...
</div>
)
}
Removed
- The
useIntersectionObserver
hook was removed in favor of theuseInView
hook.
Tests
Tests have been rewritten using react-testing-library. Before they were messing with the internals of the components to fake updates. It also just works with the new hooks.
TypeScript edition! 🎉
I decided to switch the project from Flow to TypeScript. This should ensure the TypeScript definitions match the actual implementation, without the need to manually sync the index.d.ts
file.
In the process, i've rewritten some of the internals, but it shouldn't affect the actual API.
A documentation site has also been created using docz: https://react-intersection-observer.now.sh
Breaking changes
- The deprecated
render
method has been removed - Make sure you usechildren
instead. - Instead of returning just
intersectionRatio
, you now getentry
that contains the entireIntersectionObserverEntry
element. If you're relying onintersectionRatio
, you should change your code toentry.intersectionRatio
. rootId
has been removed - An idea for each unique root is now auto generated. This always felt like temporary solution, until i implemented a smarter way.- Flow types have been removed.
Intersection Ratio
This release exposes the intersectionRatio
, giving you a bit more insight into what triggered an update.
import { InView } from 'react-intersection-observer'
const Component = () => (
<InView>
{({ inView, ref, intersectionRatio }) => (
<div ref={ref}>
<h2>{`Header inside viewport ${inView} at ${intersectionRatio}`}</h2>
</div>
)}
</InView>
)
export default Component
See #123
Hooks!
This release enables support for the useInView(ref, options)
hook. The library will work fine with older versions of React, as long as you don't use the execute the hook.
import { useRef } from 'react'
import { useInView } from 'react-intersection-observer'
const Component = () => {
const ref = useRef()
const inView = useInView(ref, {
/* Optional options */
threshold: 0,
})
return (
<div ref={ref}>
<h2>{`Header inside viewport ${inView}.`}</h2>
</div>
)
}
The release also refactors the Rollup build, which should result in a more optimized bundle.
Throw error if trying to observe element twice
This is a fix for #119
Babel 7
This release updates Babel and Rollup, and publishes the new output files.
Keep plain children
Due to popular demand (#91), I'll keep support for rendering plain children inside the <Observer />
.
This release just removes the deprecation flag. You don't need to change anything.
Simpler times
Looking at how i'm currently using react-intersection-observer, and how render props have been adapted by React, this release moves all rendering to to the children
prop.
The way to use the component is to forward the ref
to your outer element, giving you full control over the DOM.
import Observer from 'react-intersection-observer'
const Component = () => (
<Observer>
{({ inView, ref }) => (
<div ref={ref}>
<h2>{`Header inside viewport ${inView}.`}</h2>
</div>
)}
</Observer>
)
export default Component
⚠️ Breaking changes
- Deprecated
render
prop - Deprecated
tag
prop - Deprecated
child
as React.Node
They will still work for now, but you'll get a deprecation warning unless NODE_ENV is production
.
If you are currently using render
, you can move the method directly to children.
Keep on rolling
Switch the build system to Rollup, so the package now contains an umd, CommonJS and ES optimized build. 🎉
This shouldn't change anything if you are already using the package, but if you imported the files in dist
directly then that won't work anymore