如何等待React Native中Alert对话框的响应?

Fis*_*NaN 8 react-native

根据我的观察,Alert对话框似乎建立在React Native应用程序之上.因此每次调用它时都会弹出,而不是在render函数中.
问题是它不是异步任务,因此Alert无论回调函数如何,后面的代码都将继续执行.

下面的代码演示了一个Alert对话框不断弹出的情况,因为它一遍又一遍地读取相同的条形码.
(它是用TypeScript编写的.只要听从我的话,这是一个有效的片段.)

 import * as React from "react";
 import Camera from "react-native-camera";
 import { Alert } from "react-native";

 export default class BarcodeScanSreen extends React.Component<any ,any> {
 private _camera;
 private _onBarCodeRead = e => {
    if (e.type === "QR_CODE") {
        Alert.alert(
            "QRCode detected",
            "Do you like to run the QRCode?",
            [
                { text: "No", onPress: this._onNoPress },
                { text: "Yes", onPress: this._onYesPress }
            ],
            { cancelable: false }
        );
    }
};

 private _onYesPress = () => { /* process the QRCode */ }

 private _onNoPress = () => { /* close the alert dialog. */ }

render() {
    return (
        <Camera
            onBarCodeRead={this._onBarCodeRead}
            aspect={Camera.constants.Aspect.fill}
            ref={ref => (this._camera = ref)}
        >
            {/* Some another somponents which on top of the camera preview... */}
        </Camera>
    );
}
}
Run Code Online (Sandbox Code Playgroud)

有没有办法暂停JS代码并等待响应Alert

小智 5

React-native Alert不会停止执行其下面的代码。通过将其更改为异步功能,该功能可以解决对用户操作的承诺,将用作ASYNC-Alert。

const AsyncAlert = async () => new Promise((resolve) => {
  Alert.alert(
    'info',
    'Message',
    [
      {
        text: 'ok',
        onPress: () => {
          resolve('YES');
        },
      },
    ],
    { cancelable: false },
  );
});

await AsyncAlert();
Run Code Online (Sandbox Code Playgroud)

  • “await 仅在异步函数中有效”,这是最近才更改的吗?大多数答案都显示类似的内容,但这些代码示例都没有实际运行。我相信需要将等待包装在它自己的异步函数中。 (2认同)

Seb*_*ber 5

使用react-native-alert-async

我刚刚发布了一个软件包,该软件包正是这样做的,并允许等待用户的选择。它与Expo兼容。

 import AlertAsync from "react-native-alert-async";


 const myAction = async () => {

   const choice = await AlertAsync(
     'Title',
     'Message',
     [
       {text: 'Yes', onPress: () => 'yes'},
       {text: 'No', onPress: () => Promise.resolve('no')},
     ],
     {
       cancelable: true,
       onDismiss: () => 'no',
     },
   );


   if (choice === 'yes') {
     doSomething();
   }
   else {
     doSomethingElse();
   }

 }
Run Code Online (Sandbox Code Playgroud)

原始答案:我为此功能向ReactNative进行了宣传:https : //github.com/facebook/react-native/pull/20312

  • 很棒的@SebastienLorber。您的包裹对我有很大帮助!谢谢! (2认同)

nic*_*man 2

警报不会暂停代码。在这种情况下,JS 并不是唯一的问题 -Camera组件还会在本机后台中保持运行,并且onBarCodeRead无论警报是否存在,它都会触发侦听器。

您可以尝试使用文档中提到的方法_onBarCodeRead在一开始就停止相机。stopPreview()

另请注意,当前正处于从( ) 到新版本的react-native-camera迁移过程中,我没有看到方法。无论如何,一个简单的标志也可以完成这项工作。CameraRCTCameraRNCameraRNCamerastopPreview()