DEV Community

Muskan Parashar
Muskan Parashar

Posted on • Updated on

React Native WebView: Make Android pullToRefresh work without any glitches

With the help of below-mentioned pull request, you will find the pull-to-refresh feature for React Native web view Android platform.

Until the merge is done, you can integrate this feature into your app with the help of above pull request.

While implementing the feature, I faced one issue i.e pull to refresh was not working well with the side modal and while refreshing the side modal page, pull to refresh triggers on scrolling up. In case you face this issue then the below solution will work for you.

Solution:

We are required to make the changes from the website end and application end.
Firstly, at the website end, we are required to take the callback on scrolling side modals by adding the below code:


//Added a custom hook to check the scroll value of all side modals

let canCheckScrollValue = true;
export function useSideModalScrollListener(props) {
    return useEffect(() => {
            const allDiv = document.querySelectorAll(`${SIDE_MODAL_ID}`);
            allDiv?.forEach((item) => {
                if (item && item.getAttribute("listener") !== "true") {
                    item.setAttribute("listener", "true");
                    item.addEventListener("scroll", handleScroll);
                    return () => item.removeEventListener("scroll", handleScroll);
                }
            });
    }, [props.open]);
}

const handleScroll = (event) => {
    const scrollToTop = event.target?.scrollTop;
    if (scrollToTop === 0) {
        window?.ReactNativeWebView?.postMessage?.(JSON.stringify({ refreshEnabled: true }));
        canCheckScrollValue = true;
    } else if (canCheckScrollValue && scrollToTop > 10) {
        window?.ReactNativeWebView?.postMessage?.(JSON.stringify({ refreshEnabled: false }));
        canCheckScrollValue = false;
    }
};

Enter fullscreen mode Exit fullscreen mode

Here props.open can set to true when any of the side modal will open
SIDE_MODAL_ID is a classname property of div element.

Now we can use the above hook into the component where we want to check the value on scrolling side modal.


function SideModal() {
useSideModalScrollListener(props);
  return (
    <div className={`${SIDE_MODAL_ID}`}>
     ......
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

After adding a callback from the website end, we need to handle the same callback from the application end.

Below is the code to handle callback at app end:


function App() {

const onMessage = (event) => { 
const { data } = event.nativeEvent;
if (data?.includes('{')) {
      const object = JSON.parse(data);
      if (object) {
        if (object?.refreshEnabled === true) {
        //trigger refresh when the scroll reaches to top
          webViewRef?.current?.enableAndroidRefresh();
        } else if (object?.refreshEnabled === false) {
        //disable refresh on scrolling down
          webViewRef?.current?.disableAndroidRefresh();
        }
      }
    }
}
  return (
      <WebView
        source={{
          uri: 'https://github.com/react-native-webview/react-native-webview',
        }}
        onMessage={onMessage}
      />
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
ankushppie profile image
Ankush Lokhande

Very useful! Keep it up.