React Navigation didfocus 事件监听器在类组件和功能组件之间的工作方式不同

Posted

技术标签:

【中文标题】React Navigation didfocus 事件监听器在类组件和功能组件之间的工作方式不同【英文标题】:React navigation didfocus event listener works differently between class component and functional component 【发布时间】:2019-12-19 09:28:45 【问题描述】:

当我切换到此屏幕时,它会执行一些 API 调用来获取最新数据。但是,当我从另一个带有钩子版本的导航堆栈转换时,它似乎不会触发 didFocus 事件来触发 api 调用,而它在类版本中运行良好。

如何使 hooks 版本与 class 版本具有相同的行为?

这两个版本有什么区别?

类组件版本

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();
    


控制台输出

从其他导航堆栈转换到此屏幕:类版本

同一堆栈中屏幕之间的转换:类版本

挂钩版

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

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

控制台输出

从其他导航堆栈转换到此屏幕:控制台中不显示任何内容

同一堆栈中的屏幕之间的转换:hooooks

顺便说一句,这是我找到的解决方法

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();
          ;
      , []);

控制台输出

从其他导航堆栈转换到此屏幕:焦点部分

同一堆栈中的屏幕之间的转换:侦听器部分

【问题讨论】:

【参考方案1】:

我想我找到了不一致行为的根本原因。 还有一个叫useLayoutEffect的钩子

使用布局效果 签名与 useEffect 相同,但它在所有 DOM 突变后同步触发。使用它从 DOM 中读取布局并同步重新渲染。在 useLayoutEffect 中安排的更新将在浏览器有机会绘制之前同步刷新。

useLayoutEffect 会阻止绘画,而 useEffect 不会。 这证实并解释了我的猜测,即 didFocus 事件已触发,但它没有触发侦听器,因为它错过了时机

所以在我的情况下,我必须使用 useLayoutEffect 而不是 useEffect

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

【讨论】:

以上是关于React Navigation didfocus 事件监听器在类组件和功能组件之间的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

React Navigation 与 React Native Navigation [关闭]

我需要下载 react-navigation 并使用命令 npm i @react-navigation/native 并显示错误

React Navigation基本用法

react-navigation 导航路由

React Navigation V2:navigation.push 和 navigation.navigate 的区别

使用 react-navigation 禁用返回 react-native