多次调用 React 导航事件侦听器



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

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/

但是,似乎正在发生的事情是每个听众被调用两次,我不确定如何解决这个问题?

事实上,对于 react native,每当您为任何挂载的屏幕添加侦听器时,侦听器在卸载屏幕后仍然处于活动状态。每当此类侦听器尝试更改卸载屏幕的状态时,反应本机都会生成警告.
因此,每当挂载屏幕并在卸载时删除相同的屏幕时,请始终尝试添加侦听器

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 导航中通过以下方式实现


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 在屏幕安装到显示器时调用一次,当屏幕从显示器上卸载时调用相同的返回函数。

正如文档所说:

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

尝试在清理函数中清理每个订阅:

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

使用 useEffect 包装 "DeviceEventEmitter.addListener":

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

2:设置要显示事件的计数数:

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

3:最后用useEffect包装事件:

useEffect( () =>{
DeviceEventEmitter.addListener('syncEvent',
(e)=>{
console.log("NATIVE_EVENT");
console.log(e);
if(e === 'syncEnableEventData'){
handleButtonSyncEnable();
setCount(1);
}
if(e === 'syncDisableEventData'){
handleButtonSyncDisable();
setCount(1);
}

})

}, []);

最新更新