В настоящее время я пытаюсь объединить пример React Native Camera с React Navigation v2 и хочу сделать снимок в первом представлении (называется CameraView), сохраните указанное изображение в AsyncStorage, перейдите ко второму представлению (называемому GalleryView) и визуализируйте это изображение из AsyncStorage в тег изображения.
Я использую RN 0.57.1, RN-Camera 1.3.1, React Navigation 2.18.0 на компьютере с Windows 10, имитирующем телефон Android под управлением Android версии 8.0.0.
Это код для двух представлений:
CameraView.js:
import React from "react";
import {
AsyncStorage,
Dimensions,
StyleSheet,
TouchableHighlight,
View
} from "react-native";
import { RNCamera as Camera } from "react-native-camera";
const styles = StyleSheet.create({
preview: {
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
height: Dimensions.get("window").height,
width: Dimensions.get("window").width
},
capture: {
width: 70,
height: 70,
borderRadius: 35,
borderWidth: 5,
borderColor: "#FFF",
marginBottom: 15
}
});
class CameraView extends React.Component {
static navigationOptions = ({ navigation }) => ({
header: null
});
constructor(props) {
super(props);
this.state = {
imageUri: null
};
}
takePicture = async () => {
try {
const imageData = await this.camera.takePictureAsync({
fixOrientation: true
});
this.setState({
imageUri: imageData.uri
});
this._saveImageAsync();
} catch (err) {
console.log("err: ", err);
}
};
_saveImageAsync = async () => {
await AsyncStorage.setItem("imageUri", this.state.imageUri);
this.props.navigation.navigate("GalleryView");
};
render() {
return (
<Camera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
flashMode={Camera.Constants.FlashMode.off}
permissionDialogTitle={"Permission to use camera"}
permissionDialogMessage={
"We need your permission to use your camera phone"
}
>
<TouchableHighlight
style={styles.capture}
onPress={this.takePicture.bind(this)}
underlayColor="rgba(255, 255, 255, 0.5)"
>
<View />
</TouchableHighlight>
</Camera>
);
}
}
export default CameraView;
GalleryView.js:
import React from "react";
import {
AsyncStorage,
Button,
Dimensions,
StyleSheet,
Text,
Image,
View
} from "react-native";
const styles = StyleSheet.create({
preview: {
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
height: Dimensions.get("window").height,
width: Dimensions.get("window").width
},
cancel: {
position: "absolute",
right: 20,
top: 20,
backgroundColor: "transparent",
color: "#FFF",
fontWeight: "600",
fontSize: 17
}
});
class GalleryView extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: "Seismic"
});
constructor(props) {
super(props);
AsyncStorage.getItem("imageUri").then(response => {
this.setState({
imageUri: response
});
});
}
render() {
return (
<View>
<Image source={{ uri: this.state.imageUri }} style={styles.preview} />
<Text
style={styles.cancel}
onPress={() => this.state.setState({ imageData: null })}
>
X
</Text>
<Button
title="Map View"
onPress={() => this.props.navigation.popToTop()}
/>
</View>
);
}
}
export default GalleryView;
Первый упомянутый пример работает нормально, но при попытке использовать AsyncStorage я получаю приведенную ниже ошибку после привязки изображения и выполнения navigate () для второго представления.
TypeError: TypeError: null не является объектом (оценка this.state.imageUri)
Эта ошибка находится в: в GalleryView (в SceneView.js: 9) в SceneView (в StackViewLayout.js: 478) в RCTView (в View.js: 44) в RCTView (в View.js: 44) в RCTView (в View.js: 44) в AnimatedComponent (в screens.native.js: 58) в Screen (в StackViewCard.js: 42) в Card (в createPointerEventsContainer.js: 26) в контейнере (в StackViewLayout.js: 507) в RCTView (в View.js: 44) в ScreenContainer (в StackViewLayout.js: 401) в RCTView (в View.js: 44) в StackViewLayout (в withOrientation.js: 30) в withOrientation (в StackView.js: 49) в RCTView (в View.js: 44) в Transitioner (в StackView.js: 19) в StackView (в createNavigator.js: 57) в Navigator (в createKeyboardAwareNavigator.js: 11) в KeyboardAwareNavigator (в createNavigationContainer.js: 376) в NavigationContainer (в routes.js: 39) в Routes (в renderApplication.js: 34) в RCTView (в View.js: 44) в RCTView (в View.js: 44) в AppContainer (в renderApplication.js: 33)>
Я был бы признателен, если бы кто-нибудь мог указать, как правильно использовать AsyncStorage с React Navigation для рендеринга ранее сохраненного изображения из React Native Camera. Как вы, наверное, догадались, я новичок в React Native, поэтому, пожалуйста, скажите мне, правильно ли я понял концепцию или что-то в этом роде.
Заранее спасибо!
Благодаря комментарию Wainages я заставил его работать. Я добавил состояние isLoaded в GalleryView и показываю только текст «Загрузка» перед выполнением асинхронной операции.