Пользовательские события в исходном компоненте пользовательского интерфейса React Native

Я хотел бы использовать плитки OpenStreetMap в своем приложении React Native на Android, поэтому я пытаюсь обернуть компонент пользовательского интерфейса OSMDroid, как описано здесь. По большей части он работает нормально, но мне трудно понять, как правильно обрабатывать события, в частности onScroll и onZoom .

С OSMDroid вы устанавливаете DelayedMapListener для обработки событий, что довольно просто. Я подтвердил, что события обрабатываются правильно Java-стороной вверх до момента, когда должен запускаться JS-код. Однако они не запускают мой код JavaScript.

Основываясь на документации , я реализовал обработчики событий в Java в методе createViewInstance моего диспетчера представлений:

 map.setMapListener(new DelayedMapListener(new MapListener() { public boolean onScroll(ScrollEvent event) { WritableMap eventData = Arguments.createMap(); // Fill in eventData; details not important ReactContext reactContext = (ReactContext)map.getContext(); reactContext.getJSModule(RCTEventEmitter.class).receiveEvent( map.getId(), "topChange", eventData); return true; } public boolean onZoom(ZoomEvent event) { // Basically the same as above } }, 100)); 

Соответствующая часть моего JS-кода в основном идентична коду в приведенной выше документации:

 class OSMDroidMapView extends Component { constructor(props) { super(props); this._onChange = this._onChange.bind(this); } _onChange(event: Event) { console.log(event); // Handle event data } render() { return <OSMDroidMapView {...this.props} onChange={this._onChange}/> } } 

Нет никаких ошибок или признаков того, что что-то не так. Код обработчика событий Java вызывается правильно. В случае возникновения события в коде JS ничего не происходит. Кто-нибудь знает, как это сделать правильно? Я чувствую, что мне, должно быть, недостает базовой концепции.

Solutions Collecting From Web of "Пользовательские события в исходном компоненте пользовательского интерфейса React Native"

Чтобы отправить пользовательские события в Javascript, вы можете использовать RCTDeviceEventEmitter:

На родной стороне:

 import com.facebook.react.modules.core.DeviceEventManagerModule; ... public boolean onScroll(ScrollEvent event) { WritableMap eventData = Arguments.createMap(); // Fill in eventData; details not important ReactContext reactContext = (ReactContext)map.getContext(); reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("YouCustomEventName", eventData); return true; } 

Внутри вашего JS-модуля вам просто нужно зарегистрировать прослушиватель с помощью DeviceEventEmitter:

 class OSMDroidMapView extends Component { constructor(props) { super(props); this._onChange = this._onChange.bind(this); } componentWillMount() { DeviceEventEmitter.addListener('YouCustomEventName', this._onChange); } componentWillUnmount() { DeviceEventEmitter.removeListener('YouCustomEventName', this._onChange); } _onChange(event: Event) { console.log(event); // Handle event data } render() { return <OSMDroidMapView {...this.props} onChange={this._onChange}/> } } 

Надеюсь, поможет.