我不知道为什么当我触发一个事件时 DeviceEventEmitter.addListener 它已经发出一次但是听了两次。
我有一个 Base 组件,它已经在每个屏幕上添加,例如
<View>
{this.props.children}
<ModalComponent />
</View>
ModalComponent 应该能够在 ModalVisible 事件的任何时候打开它。
constructor (props) {
super(props)
this.state = {
modalVisible: false
}
}
componentDidMount() {
DeviceEventEmitter.addListener('ModalVisible', this.onModalVisible)
}
componentWillUnmount () {
DeviceEventEmitter.removeListener('ModalVisible', this.onModalVisible)
}
onModalVisible = (args) => {
console.log(['ModalVisible', args]) // logging twice
this.setState({
modalVisible: args.visible
})
}
close () {
this.setState({
modalVisible: false
})
}
onRequestClose = () => {
this.close()
}
render() {
return (
<Modal animationType={'slide'} transparent={false} visible={this.state.modalVisible} onRequestClose={this.onRequestClose}>
...
</Modal>
)
}
我有一台服务器,在需要时发出事件
static show (data) {
console.log(['Service.show', data]) // only once
DeviceEventEmitter.emit('ModalVisible', { visible: true })
}
当Service.show被调用时,第一个日志只出现一次,但是立即出现在 addListener ,它被记录了两次。
我已经尝试了
this.listener = DeviceEventEmitter.addListener(...)
this.listener.remove()
和
this.onModalVisible.bind(this)
但它给了我同样的问题。
除此之外,在同一时刻,模态已被复制,当我关闭时,我有两个模态要接近。
我也尝试在没有父组件的情况下在新屏幕中加载所有这些,以查看是否可能出现问题,mas no。它仍然。
答案 0 :(得分:1)
今天,我也遇到了这个问题。我看一下源代码js。我发现DeviceEventEmit.addListener
实际上会调用EventSubscriptionVendor.addSubscription method
。
_subscriber: EventSubscriptionVendor;
addListener(
eventType: string,
listener: Function,
context: ?Object,
): EmitterSubscription {
return (this._subscriber.addSubscription(
eventType,
new EmitterSubscription(this, this._subscriber, listener, context),
): any);
}
addSubscription(
eventType: string,
subscription: EventSubscription,
): EventSubscription {
invariant(
subscription.subscriber === this,
'The subscriber of the subscription is incorrectly set.',
);
if (!this._subscriptionsForType[eventType]) {
this._subscriptionsForType[eventType] = [];
}
const key = this._subscriptionsForType[eventType].length;
//here is the point
this._subscriptionsForType[eventType].push(subscription);
subscription.eventType = eventType;
subscription.key = key;
return subscription;
}
在内部方法中,会将侦听器的argus函数推入数组;当我们多次调用它时,它将推动许多侦听器的功能。
因此在项目中,我们必须避免多次调用它,并且在卸载组件之后,必须将其删除。
答案 1 :(得分:0)
我在使用socket.io触发/注册两次事件时遇到了同样的问题,我的问题是因为我在DidMount方法上添加了eventListeners。但是由于我的组件已经多次安装,因此它还多次添加了eventListeners。
我的猜测是你多次使用相同的组件,因此多次添加相同的eventListener。尝试将eventsListener添加到另一个只调用一次的地方。