React navigation didfocus event listener works differently between class component and functional component

喜夏-厌秋 提交于 2020-01-02 02:51:10

问题


When I transition to this screen, it will do some API calls to fetch the latest data. But it seems not trigger the didFocus event to fire the api calls when I transition from another navigation stack with hooks version while it works well with class version.

How do I make hooks version have the same behavior as class version?

What's the difference between this two version?

class component version

class someScreen extends Component {
    componentDidMount() {
       const {
           navigation,
       } = this.props;

       this.navFocusListener = navigation.addListener('didFocus', () => {
         // do some API calls here
         console.log("class version");
         API_CALL();
       });
    }

    componentWillUnmount() {
        this.navFocusListener.remove();
    }
}

console output

transition from other navigation stack to this screen: class version

transition between screens in same stack: class version

Hooks version

const someScreen = ({
 navigation,
}) => {
    useEffect(() => {
        const navFocusListener = navigation.addListener('didFocus', () => {
        // do some API calls here
        API_CALL();
        console.log('hooooks');
    });

    return () => {
        navFocusListener.remove();
    };
  }, []);
}

console output

transition from other navigation stack to this screen: nothing is shown in console

transition between screens in same stack: hooooks

BTW, here is the workaround solution I found

const someScreen = ({
 navigation,
}) => {
      useEffect(() => {
          const isFocused = navigation.isFocused();

          // manually judge if the screen is focused
          // if did, fire api call
          if (isFocused) {
             // do the same API calls here
             API_CALL();
             console.log('focused section');
          }

          const navFocusListener = navigation.addListener('didFocus', () => {
              // do some API calls here
              API_CALL();
              console.log('listener section');
          });

          return () => {
              navFocusListener.remove();
          };
      }, []);
}

console output

transition from other navigation stack to this screen: focused section

transition between screens in same stack: listener section


回答1:


I guess I found the root cause of the inconsistent behavior. There is another hook called useLayoutEffect

useLayoutEffect The signature is identical to useEffect, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.

the useLayoutEffect will block the painting while the useEffect will not. That confirm and explains my guess that the didFocus event had fired, but it didn't trigger the listener since it miss the timing

so in my case, I have to use useLayoutEffect instead of useEffect

reference: https://kentcdodds.com/blog/useeffect-vs-uselayouteffect https://reactjs.org/docs/hooks-reference.html#uselayouteffect



来源:https://stackoverflow.com/questions/57467317/react-navigation-didfocus-event-listener-works-differently-between-class-compone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!