Consider a scenario where you need to observe a list of components. You can streamline this process by creating a function to manage the observation for each component. In this case, the example utilizes the ScrollObserver functional component, which uses React hooks to set up an IntersectionObserver for observing child elements. The useEffect hook is used to initiate observation when the component mounts and the useRef hook is used to keep track of the observed elements. Each child element is wrapped in a div with a ref, and these references are stored in the fadersRef array for observation.

Here’s an example using React hooks:


const ScrollObserver = ({ children }) => {
  const fadersRef = useRef([]);

  const appearOptions = {
    threshold: 1,

  const appearOnScroll = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (!entry.isIntersecting) {
      } else {'appear');
  }, appearOptions);

  useEffect(() => {
    fadersRef.current.forEach((fader) => {
    return () => {
  }, []);

  return (
      {, (child, index) => {
        const ref = React.createRef();
        fadersRef.current[index] = ref.current;
        return React.cloneElement(child, { ref });


import ScrollObserver from './ScrollObserver';

const App = () => {
  return (
      <div className="fade-in">Element 1</div>
      <div className="fade-in">Element 2</div>
      {/* Add more elements as needed */}
export default App;

Alternatively, for those who prefer a custom hook approach, the same functionality can be achieved by encapsulating the logic within a custom hook named useScrollObserver. This hook abstracts the intersection observation logic and returns the fadersRef array. The ScrollObserver component then becomes a simple wrapper around this custom hook, enhancing reusability and separation of concerns.

Support On Demand!