我已按以下方式添加了侦听器(尝试同时放入构造函数和componentDidMount): AppState.addEventListener('更改',this._handleAppStateChange);
并在componentWillUnmount方法中以下列方式删除了侦听器:
AppState.removeEventListener('更改',this._handleAppStateChange);
在回调函数中:
_handleAppStateChange = (nextAppState) => {
setTimeout(() => {
alert('App state: ' + this.state.appState);
alert('Next App state: ' + nextAppState);
}, 0);
}
它会多次发出警报。 它不会删除一次配置的侦听器。 如果有人知道,请告诉我?
答案 0 :(得分:1)
根据代码的外观,我假设您正在使用类组件。我最终解决它的方法是创建一个指针函数,该指针函数指向this
范围内的实际函数,而无需使用.bind(this)
。
例如
// Actual Function
handleAppStateChange(state) {
// Work your magic!
}
// Pointer
handleAppStateChangeCall = (state) => this.handleAppStateChange(state);
// Setup listener event
setupAppStateListener() {
AppState.addEventListener("change", this.handleAppStateChangeCall);
}
// Clear listener event
clearAppStateListener() {
AppState.addEventListener("change", this.handleAppStateChangeCall);
}
// Mounted Hook
componentDidMount() {
setupAppStateListener();
}
// Unmount Hook
componentWillUnmount() {
clearAppStateListener()
}
答案 1 :(得分:0)
您必须从ComponentWillUnmount
功能
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
答案 2 :(得分:0)
设置状态是异步过程。因此,在componentWillUnmount中不要将它用作组件获取卸载,并且仍然对于该场景,setState正在进行中,从而导致警报。
答案 3 :(得分:0)
可能是由于您正在监听的功能发生改变
this.props.navigation.addListener(
'didFocus',
() => {
AppState.addEventListener('change', this.handleAppStateChange)
}
)
this.props.navigation.addListener(
'willBlur',
() => {
AppState.removeEventListener('change', this.handleAppStateChange)
}
)
正常工作
this.props.navigation.addListener(
'didFocus',
() => {
AppState.addEventListener('change', this.handleAppStateChange.bind(this))
}
)
this.props.navigation.addListener(
'willBlur',
() => {
AppState.removeEventListener('change', this.handleAppStateChange.bind(this))
}
)
不起作用 所以也许你需要这样
this.handleAppStateChange = this.handleAppStateChange.bind(this)
在您的构造函数中
答案 4 :(得分:0)
最近几天遇到了同样的问题。 我终于通过将应用程序状态管理迁移到App.js组件并创建了服务管理器来对其进行管理。
下面是我的App.js
的样子:
import {AppState } from "react-native";
import {AppStateService} from "YOUR_PATH_TO_THE_NEXT_FILE";
export default function App() {
// Listen to app state
AppStateService.init();
useEffect(() => {
AppState.addEventListener('change', AppStateService.getInstance().handleAppStateChange);
return (() => {
AppState.removeEventListener('change', AppStateService.getInstance().handleAppStateChange);
})
}, []);
return (/*Rendering stuff (navigation, error boundary, ...*/);
}
AppStateService.js
:
/**
* Class to allow us to refer to the app state service
*/
export class AppStateService {
static instance;
static STATE_ACTIVE = 'active';
static STATE_INACTIVE = 'inactive';
static STATE_BACKGROUND = 'background';
static STATE_NOT_LAUNCHED = 'not_launched';
previousState = AppStateService.STATE_NOT_LAUNCHED;
currentState = AppStateService.STATE_ACTIVE;
handlers = {};
appLaunchId = 0;
/**
* @returns {AppStateService}
*/
static getInstance() {
if(!this.instance){
this.instance = new AppStateService();
}
return this.instance;
}
static init = () => {
// This func need to be call in the App.js, it's just here to create the instance
const instance = AppStateService.getInstance();
instance.appLaunchId = new Date().getTime() / 1000;
}
handleAppStateChange = (nextState) => {
if(nextState !== this.currentState) {
this.previousState = this.currentState;
this.currentState = nextState;
for (const [key, handler] of Object.entries(this.handlers)) {
handler(nextState);
}
}
}
getCurrentState = () => {
return this.currentState;
}
getPreviousState = () => {
return this.previousState;
}
addStateHandler = (key, handler) => {
this.handlers[key] = handler;
}
hasStateHandler = (key) => {
if( this.handlers[key] ){
return true;
}
return false;
}
removeStateHandler = (key) => {
delete this.handlers[key];
}
}
现在这里是如何在应用程序组件中的任何位置调用它的方法:
export default class RandomComponent extends React.Component {
componentDidMount() {
// Check app going background or not
this.handleAppStateChange = this.handleAppStateChange.bind(this);
AppStateService.getInstance().addStateHandler('myListenerCustomKey', this.handleAppStateChange);
}
componentWillUnmount() {
// Remove app state change listener
AppStateService.getInstance().removeStateHandler('myListenerCustomKey');
}
handleAppStateChange = (nextAppState) => {
console.log("I'm going to be -" + nextAppState + "- while I was -" + AppStateService.getInstance().getPreviousState() + "-");
}
}
通过这种方式,您可以在应用程序中的任何位置侦听应用程序的前台/非活动/后台状态,并正确订阅/取消订阅这些事件。