From cbaffc20e6a509929a06c5cd7bdb54022a5225e7 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 27 Sep 2021 14:35:35 +0200 Subject: [PATCH] fix: Fix `system/view-not-found` error caused by `setFrameProcessor` race condition (#459) * Remove `onLayout` hack * Add `system/view-not-found` error --- src/Camera.tsx | 27 ++++++++++----------------- src/CameraError.ts | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/Camera.tsx b/src/Camera.tsx index e99c818..e366674 100644 --- a/src/Camera.tsx +++ b/src/Camera.tsx @@ -1,13 +1,5 @@ import React from 'react'; -import { - requireNativeComponent, - NativeModules, - NativeSyntheticEvent, - findNodeHandle, - NativeMethods, - Platform, - LayoutChangeEvent, -} from 'react-native'; +import { requireNativeComponent, NativeModules, NativeSyntheticEvent, findNodeHandle, NativeMethods, Platform } from 'react-native'; import type { FrameProcessorPerformanceSuggestion } from '.'; import type { CameraDevice } from './CameraDevice'; import type { ErrorWithCause } from './CameraError'; @@ -93,14 +85,18 @@ export class Camera extends React.PureComponent { this.onInitialized = this.onInitialized.bind(this); this.onError = this.onError.bind(this); this.onFrameProcessorPerformanceSuggestionAvailable = this.onFrameProcessorPerformanceSuggestionAvailable.bind(this); - this.onLayout = this.onLayout.bind(this); this.ref = React.createRef(); this.lastFrameProcessor = undefined; } private get handle(): number | null { const nodeHandle = findNodeHandle(this.ref.current); - if (nodeHandle == null) console.error('Camera: findNodeHandle(ref) returned null! Does the Camera view exist in the native view tree?'); + if (nodeHandle == null || nodeHandle === -1) { + throw new CameraRuntimeError( + 'system/view-not-found', + "Could not get the Camera's native view tag! Does the Camera View exist in the native view-tree?", + ); + } return nodeHandle; } @@ -370,17 +366,15 @@ export class Camera extends React.PureComponent { global.unsetFrameProcessor(this.handle); } - private onLayout(event: LayoutChangeEvent): void { - if (!this.isNativeViewMounted) { + componentDidMount(): void { + requestAnimationFrame(() => { this.isNativeViewMounted = true; if (this.props.frameProcessor != null) { // user passed a `frameProcessor` but we didn't set it yet because the native view was not mounted yet. set it now. this.setFrameProcessor(this.props.frameProcessor); this.lastFrameProcessor = this.props.frameProcessor; } - } - - this.props.onLayout?.(event); + }); } /** @internal */ @@ -419,7 +413,6 @@ export class Camera extends React.PureComponent { onError={this.onError} onFrameProcessorPerformanceSuggestionAvailable={this.onFrameProcessorPerformanceSuggestionAvailable} enableFrameProcessor={frameProcessor != null} - onLayout={this.onLayout} /> ); } diff --git a/src/CameraError.ts b/src/CameraError.ts index 75cf8b1..8c6a885 100644 --- a/src/CameraError.ts +++ b/src/CameraError.ts @@ -43,7 +43,7 @@ export type CaptureError = | 'capture/photo-not-enabled' | 'capture/aborted' | 'capture/unknown'; -export type SystemError = 'system/no-camera-manager'; +export type SystemError = 'system/no-camera-manager' | 'system/view-not-found'; export type UnknownError = 'unknown/unknown'; /**