首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多次响应导航事件侦听器

多次响应导航事件侦听器
EN

Stack Overflow用户
提问于 2020-06-07 18:05:51
回答 3查看 3.8K关注 0票数 10

我正在尝试使用功能组件方法在react导航上实现一些侦听器:

代码语言:javascript
运行
复制
const ExampleComponent = () => {

  const [subs, setSubs] = React.useState([]); 
  React.useEffect(() => {
    setSubs([
      navigation.addListener('willFocus', () => console.log('will focus')),
      navigation.addListener('willBlur', () => console.log('will blur')),
      navigation.addListener('didFocus', () => console.log('did focus')),
      navigation.addListener('didBlur', () => console.log('did blur')),
    ]);

    return () => {
      setSubs([]) 
    }
  }, [])

  return (
    ...
  )
};

以下建议:https://fantashit.com/navigation-listeners-firing-multiple-times-per-event/

然而,似乎正在发生的是,每个侦听器被调用两次,而我不知道如何解决这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-07 22:25:50

正如文档所说:

addListener返回一个函数,该函数可以被调用以取消订阅事件。

尝试清理清理功能中的每个订阅:

代码语言:javascript
运行
复制
React.useEffect(() => {
  const unSubs = [
    navigation.addListener('willFocus', () => console.log('will focus')),
    navigation.addListener('willBlur', () => console.log('will blur')),
    navigation.addListener('didFocus', () => console.log('did focus')),
    navigation.addListener('didBlur', () => console.log('did blur')),
  ]

  return function cleanup() {
    unSubs.forEach((unSub) => {
      unSub()
    })
  }
}, [])
票数 7
EN

Stack Overflow用户

发布于 2021-09-16 19:59:46

事实上,当您为任何已挂载的屏幕添加侦听器时,侦听器在屏幕卸载之后仍然处于活动状态。每当这些侦听器试图更改未挂载屏幕的状态时,响应本机将生成警告。

因此,无论何时挂载屏幕,总是尝试添加侦听器,并在卸载时删除相同的监听器。

代码语言:javascript
运行
复制
const ExampleComponent = () => {

  const [subs, setSubs] = React.useState([]); 
  React.useEffect(() => {
    setSubs([
      navigation.addListener('willFocus', () => console.log('will focus')),
      navigation.addListener('willBlur', () => console.log('will blur')),
      navigation.addListener('didFocus', () => console.log('did focus')),
      navigation.addListener('didBlur', () => console.log('did blur')),
    ]);

    const unsubscribe = () =>{
    navigation.removeAllListeners();
    }
    // Remove all listeners, because there have to be no listeners on unmounted screen
    return () => unsubscribe();
  }, [])

在react导航中,也可以通过以下操作实现相同的目标

代码语言:javascript
运行
复制
useFocusEffect(
    React.useCallback(() =>{

      // Listening on the refresh event
       RefreshEventEmitter.addListener("refresh", () => {
         console.log("Refresh event emitted");
       });

      // ----------------------------------------------
      // Removing all the listeners, so that screen does not re-render after unmounting..
      const unsubscribe = () => {
        RefreshEventEmitter.removeAllListeners();
      };

 
      // Returned function is called when screen is unmounted from display!!
      return () => unsubscribe();
    }, [])
  );

当屏幕被挂载到显示器时,调用一次useFocusEffect,当屏幕从显示器上卸载时,返回函数也会被调用。

票数 9
EN

Stack Overflow用户

发布于 2022-08-17 10:32:09

将"DeviceEventEmitter.addListener“用useEffect包装:

1:import React, { useEffect, useState } from "react";

2:设置不想显示事件的计数:

const [buttonSyncEnabled, setButtonSyncEnabled] = useState(false);

3:最后用useEffect包装事件:

代码语言:javascript
运行
复制
useEffect( () =>{
DeviceEventEmitter.addListener('syncEvent',
(e)=>{
  console.log("NATIVE_EVENT");
  console.log(e);
  if(e === 'syncEnableEventData'){
    handleButtonSyncEnable();
    setCount(1);
  }
  if(e === 'syncDisableEventData'){
    handleButtonSyncDisable();
    setCount(1);
  }
  
  })


}, []);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62249610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档