title: Execute a function in a child component when a scroll event occurs in a parent in React?
body: <p>My project is React Native but this is a general React question. I need to get the Y position of a View relative to the root element (so I can do some calculations against the <code>pageY</code> event from a <code>PanResponder</code>). This View is in a parent component with a ScrollView and I need this value to update as you scroll as it will have changed. </p>
  
  <p>I can do the measurement in the View with <code>onLayout</code> and the <code>measure</code> callback so my question is how should I recalculate when scrolling occurs? I have a solution that works but I'm not sure if it's ideal in terms of performance or if I've gone about it in a needlessly verbose way.</p>
  
  <p>My solution is to use the <code>onScroll</code> event to set a piece of state which I pass down to the View, and then use it as a dependancy in <code>useEffect</code> which re-fires the calculation. Im not sure if it's efficient as the View component doesn't actually use this value, it only needs the event that the scroll position has changed. So the View is currently re-rendering every-time you scroll:</p>
  
  <pre><code>export default function App() {
    const [scrollPosition, setScrollPosition] = React.useState(null);
  
    return (
      &lt;ScrollView
        onScroll={(e) =&gt; {
          setScrollPosition(e.nativeEvent.contentOffset.y);
        }}
        scrollEventThrottle={16}
      &gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;Text&gt;Text&lt;/Text&gt;
        &lt;ContainerFunctional scrollPosition={scrollPosition} /&gt;
      &lt;/ScrollView&gt;
    );
  }
  
  const ContainerFunctional = ({ scrollPosition }) =&gt; {
    const items = new Array(100).fill("");
    const marker = React.useRef(null);
  
    React.useEffect(() =&gt; {
      marker.current.measure((x, y, width, height, pageX, pageY) =&gt; {
        if (scrollPosition !== null) {
          console.log("on scroll ", pageY);
        }
      });
    }, [scrollPosition]);
  
    return (
      &lt;View
        ref={marker}
        onLayout={() =&gt; {
          if (marker.current) {
            marker.current.measure((x, y, width, height, pageX, pageY) =&gt; {
              console.log("initial ", pageY);
            });
          }
        }}
      &gt;
        {items.map((item, index) =&gt; {
          return &lt;Text key={index}&gt;{index}&lt;/Text&gt;;
        })}
      &lt;/View&gt;
    );
  };
  </code></pre>