根据我的观察,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>
);
}
}
有没有办法暂停JS代码并等待Alert
的响应?
答案 0 :(得分:5)
我刚刚发布了一个软件包,该软件包正是这样做的,并允许等待用户的选择。它与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();
}
}
原始答案:我为此功能向ReactNative做了PR:https://github.com/facebook/react-native/pull/20312
答案 1 :(得分:2)
React-native Alert不会停止执行其下面的代码。通过将其更改为异步功能,可以解决对用户操作的承诺,将作为ASYNC-Alert。
const AsyncAlert = async () => new Promise((resolve) => {
Alert.alert(
'info',
'Message',
[
{
text: 'ok',
onPress: () => {
resolve('YES');
},
},
],
{ cancelable: false },
);
});
await AsyncAlert();
答案 2 :(得分:1)
警报不会暂停代码。在这种情况下,JS不是唯一的问题 - Camera
组件也在后台继续运行,它是本机的,它将触发onBarCodeRead
侦听器,无论警报是否存在。
您可以尝试使用docs中提到的_onBarCodeRead
方法在stopPreview()
处开始停止相机。
另请注意,react-native-camera
目前正处于从Camera
(RCTCamera
)到RNCamera
的迁移过程中以及新RNCamera
中的stopPreview()
。请参阅x.set_index('b').a.str.get_dummies(sep=',').replace(0,np.nan).stack().reset_index().drop(0,1)
Out[481]:
b level_1
0 1 y
1 1 x
2 0 r
3 0 t
4 0 x
5 0 x
6 1 t
7 1 y
方法。无论如何,一个简单的旗帜也可以完成这项任务。
答案 3 :(得分:1)
这是一个简单的解决方案。
这里使用的技巧是使一个函数调用按钮的void wavelet_tree_to_stream(std::ostream& to, const wavelet_tree* node) {
to << "{"
to << "\"alphabet\":\"" << node->alphabet << "\"";
to << ',';
to << "\"middle\": \"" << node->middle << "\"";
if(nullptr != node->Left) {
to << ",\"Left\" : ";
wavelet_tree_to_stream(to, node->Left);
}
if(nullptr != node->Right) {
to << ",\"Right\" : ";
wavelet_tree_to_stream(to, node->Right);
}
to << "}";
}
......
wavelet_tree_to_stream(fstream, root);
函数,然后使用按钮的索引来解决promise。请注意,这要求警报不可取消。
onPress
用法:
showAsyncAlert = (title, message, buttons, options) => {
return new Promise((resolve, reject) => {
// We can't detect a cancellation, so make sure the Alert is not cancellable.
options.cancellable = false
buttons.forEach((button, index) => {
let onPress = button.onPress
button.onPress = option => {
if (onPress) {
onPress(option)
}
resolve(index)
}
})
Alert.alert(title, message, buttons, options)
})
}
答案 4 :(得分:0)
我对此有一些解决方法,如果您具有以下警报功能
Alert.alert(
'Delete comment?',
'Are you sure you want to delete this comment?',
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{ text: 'yes', onPress:() => this.props.deleteComment(commentId),
],
{ cancelable: false },
);
//call after comment is deleted
refreshPage();
此代码不等待警报的响应,它将立即执行refreshPage()
。
因此,您可以做类似
的操作 Alert.alert(
'Delete comment?',
'Are you sure you want to delete this comment?',
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{ text: 'yes', onPress: async () => {await this.props.deleteComment(commentId);refreshPage();},
],
{ cancelable: false },
);
答案 5 :(得分:0)
为此,我喜欢使用两个小的实用程序函数,它们会循环/休眠直到满足某些条件。用script
调用它以阻止执行并将条件作为函数提供。
除了带有警报,您还可以使用它来等待其他情况。
await
像这样使用:
export function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
export async function until(fn, ms=10) {
while (!fn()) await sleep(ms)
}