microsoft / clarity-apps

Repo for distributing Clarity Apps packages
MIT License
37 stars 2 forks source link

[Discussion] Why we need to use `useFocusEffect` to set current screen instead of using Screen-Tracking from RNavigation doc? #23

Closed flixyudh closed 7 months ago

flixyudh commented 7 months ago

I just curious why we need to use useFocusEffect, React Navigation has created a doc about Screen Tracking. does it has different approach?

React Navigation Screen Tracking code with customize example:

import {
  NavigationContainer,
  useNavigationContainerRef,
} from '@react-navigation/native';

export default () => {
  const navigationRef = useNavigationContainerRef();
  const routeNameRef = useRef();

  return (
    <NavigationContainer
      ref={navigationRef}
      onReady={() => {
        routeNameRef.current = navigationRef.getCurrentRoute().name;
      }}
      onStateChange={async () => {
        const previousRouteName = routeNameRef.current;
        const currentRouteName = navigationRef.getCurrentRoute().name;

        if (previousRouteName !== currentRouteName) {
          routeNameRef.current = currentRouteName;

          // add setCurrentScreenName to set screen name automatically
          await setCurrentScreenName(currentRouteName);
        }
      }}
    >
      {/* ... */}
    </NavigationContainer>
  );
};
SaadeldinBadr commented 7 months ago

Hello @zxccvvv, You don't need to use useFocusEffect to set the current screen name; the docs are only showing an example that the screen name should be set upon navigating to it. Your code example should work fine, you can remove the await keyword before setCurrentScreenName as it has no effect, and you can also call setCurrentScreenName in onReady too to set the first screen name.

<NavigationContainer
      ref={navigationRef}
      onReady={() => {
        routeNameRef.current = navigationRef.getCurrentRoute().name;
        setCurrentScreenName(routeNameRef.current);
      }}
      onStateChange={() => {
        const previousRouteName = routeNameRef.current;
        const currentRouteName = navigationRef.getCurrentRoute().name;

        if (previousRouteName !== currentRouteName) {
          routeNameRef.current = currentRouteName;
          setCurrentScreenName(currentRouteName);
        }
      }}
    >
      {/* ... */}
</NavigationContainer>