我试图让我的浏览器将一些DOM事件发送到React VR组件中。
我得到的最接近的是使用"原生模块的代码。"
(client.js)
export default class WindowEventsModule extends Module {
constructor() {
super('WindowEventsModule');
this.listeners = {};
window.onmousewheel = event => {
this._emit('onmousewheel', event);
};
}
init(rnctx) {
this._rnctx = rnctx;
}
_emit(name, ob) {
if (!this._rnctx) {
return;
}
Object.keys(this.listeners).forEach(key => {
this._rnctx.invokeCallback(this.listeners[key], [ob]);
});
}
onMouseWheel(listener) {
const key = String(Math.random());
this.listeners[key] = listener;
return () => {
delete this.listeners[key];
};
}
}
(WindowEventsModule.js)
WindowEvents.onMouseWheel(function() {})
所以我的组件现在可以调用this._rnctx.callFunction()
,并从DOM世界获得回调。
不幸的是,这仅适用一次。在呼叫后,RN显然会使我的回调无效。
我还研究了a = b + c + d + e;
,它可以调用一个名为" callable module"的东西上的任意函数。我不知道如何从那里到我的组件。
我有什么遗失的吗?将任意消息从本地世界提供给ReactVR后台工作程序的模式是什么?
答案 0 :(得分:2)
我想通了......等等。
诀窍是创建我自己的" BatchedBridge"然后我可以使用上下文中的callFunction()
来访问。
(index.vr.js)
import React from 'react';
import {AppRegistry, asset, Pano, View} from 'react-vr';
import BatchedBridge from 'react-native/Libraries/BatchedBridge/BatchedBridge';
import lodash from 'lodash';
class BrowserBridge {
constructor() {
this._subscribers = {};
}
subscribe(handler) {
const key = String(Math.random());
this._subscribers[key] = handler;
return () => {
delete this._subscribers[key];
};
}
notifyEvent(name, event) {
lodash.forEach(this._subscribers, handler => {
handler(name, event);
});
}
}
const browserBridge = new BrowserBridge();
BatchedBridge.registerCallableModule(BrowserBridge.name, browserBridge);
export default class WelcomeToVR extends React.Component {
constructor(props) {
super(props);
this.onBrowserEvent = this.onBrowserEvent.bind(this);
}
componentWillMount() {
this.unsubscribe = browserBridge.subscribe(this.onBrowserEvent);
}
onBrowserEvent(name, event) {
// Do the thing here
}
componentWillUnmount() {
if (this.unsubscribe) {
this.unsubscribe();
delete this.unsubscribe;
}
}
render() {
//...
}
};
AppRegistry.registerComponent('WelcomeToVR', () => WelcomeToVR);
(WindowEventsModule.js)
import {Module} from 'react-vr-web';
import lodash from 'lodash';
const eventToOb = (event) => {
const eventOb = {};
for (let key in event) {
const val = event[key];
if (!(lodash.isFunction(val) || lodash.isObject(val))) {
eventOb[key] = val;
}
}
return eventOb;
};
export default class WindowEventsModule extends Module {
constructor() {
super('WindowEventsModule');
this._bridgeName = 'BrowserBridge';
window.onmousewheel = event => {
this._emit('onmousewheel', event);
};
}
init(rnctx) {
this._rnctx = rnctx;
}
_emit(name, event) {
if (!this._rnctx) {
return;
}
const eventOb = eventToOb(event);
this._rnctx.callFunction(this._bridgeName, 'notifyEvent', [name, eventOb]);
}
}
这感觉非常hacky,因为它似乎不会被BatchedBridge
暴露给消费者。
但是在有更好的选择之前,我想我会选择这个。