将一个组件中的特定状态传递给另一组件

时间:2019-06-04 12:31:21

标签: javascript reactjs react-native state expo

我正在开发一个需要用户拍照的应用程序,我已经能够处理摄像头组件,但是我对如何将拍摄的图像传递给摄像头组件所在的另一个组件屏幕一无所知已导入。 下面是相机组件以及我要传递相机组件新状态的位置。

我真的没有尝试过任何具体的事情,因为我不知道我该传递状态还是道具。

相机组件

      import React from 'react';
      import { Text, View, TouchableOpacity, StyleSheet, ScrollView, Image, Alert, Modal, } from 'react-native';
      import { Camera, Permissions } from 'expo';
      import { Entypo, Ionicons, MaterialIcons, } from '@expo/vector-icons';


      export default class Camera extends React.Component {
        state = {
          hasCameraPermission: null,
          type: Camera.Constants.Type.back,
        };

        async componentDidMount() {
          const { status } = await Permissions.askAsync(Permissions.CAMERA);
          this.setState({ hasCameraPermission: status === 'granted' });
        }

        takePicture = async () => {
          if (this.camera) {
            const photo = await this.camera.takePictureAsync({ base64: true });

            const formData = new FormData();
            formData.append('image', photo.base64);
            formData.append('type', 'base64');

            this.setState({
              latestImage: photo.uri,
              isCameraVisible: false
            });
        }
        };

        openCamera = () => {
          const { hasCameraPermission } = this.state;
          if (!hasCameraPermission) {
            Alert.alert('Error', 'No access to camera');
          } else {
            this.setState({ isCameraVisible: true });
          }
        };

        closeCamera = () => {
          this.setState({
            isCameraVisible: false
          });
        };

                render() {
                  const { hasCameraPermission } = this.state;

                  if (hasCameraPermission === null) {
                  return <View />;
                  } else if (hasCameraPermission === false) {
                    return <Text>No access to camera</Text>;
                  } else {
                    return (
                      <View style={styles.container}>
                        {!this.state.isCameraVisible && (
                            <View style={styles.mainContent}>
                              <View style={styles.buttonContainer}>
                                <TouchableOpacity onPress={this.openCamera}>
                                  <MaterialIcons name="camera-alt" size={40} color="#1083bb" />
                                </TouchableOpacity>
                              </View>
                              {this.state.latestImage && (
                                <Image
                                  style={styles.latestImage}
                                  resizeMode='cover'
                                  source={{ uri: this.state.latestImage }}
                                />
                              )}
                            </View>
                        )}

                        {this.state.isCameraVisible && (
                          <Modal
                            transparent
                            animationType={'slide'}
                            visible={this.state.ModalVisibleStatus}
                          >
                              <View
                              style={{
                                flex: 1, backgroundColor: '#FFF'
                              }}
                              >
                          <Camera
                            style={styles.camera}
                            type={this.state.type}
                            ref={ref => {
                              this.camera = ref;
                            }}
                          >
                  <View style={styles.cameraContent}>
                    <View
                      style={{
                        flex: 1,
                        backgroundColor: 'transparent',
                        flexDirection: 'row',
                      }}
                    >
                      <TouchableOpacity
                        style={styles.buttonCamera}
                        onPress={this.takePicture}
                      >
                        <Entypo name="circle" size={50} color="#FFFFFF" />
                      </TouchableOpacity>

                      <TouchableOpacity
                        style={styles.buttonCloseCamera}
                        onPress={this.closeCamera}
                      >
                        <MaterialIcons name="close" size={25} color="#FFFFFF" />
                      </TouchableOpacity>
                    </View>
                    </View>
                </Camera>
                </View>
                </Modal>
              )}
              </View>
            );
          }
        }
      }
      });

我要预览所拍摄图像的索引组件

      import React, { Component } from 'react';
      import { View, StyleSheet, Text, TouchableHighlight, TouchableOpacity,
      Modal, Button, KeyboardAvoidingView, Keyboard } from 'react-native';
      import { Block, Input } from '../../components';
      import { theme } from '../../constants';
      import Camera from './upload';


      class Details extends Component {
        constructor(props) {
          super(props);
          this.state = {
            receiverName: '',
            receiverPhone: '',
            ModalVisibleStatus: false,

          };
        }

      ShowModalFunction(visible) {
        this.setState({
          ModalVisibleStatus: visible
        });
        Keyboard.dismiss();
      }

      handleChangeName = (receiverName) => {
        this.setState({
          receiverName
        });
      }

      handleChangePhone = (receiverPhone) => {
        this.setState({
          receiverPhone
        });
      }


        render() {
          return (
            <View
            style={styles.Container}
            >
                  <Input
                    placeholder="Inputs"
                    phone
                    autoCorrect
                    style={styles.input}
                    onChangeText={this.handleChangePhone}
                    defaultValue={this.state.receiverPhone}
                    onFocus={() => {
                      this.ShowModalFunction(true);
                      Keyboard.dismiss();
                     }}
                     autoFocus={false}
                  />
              <View
                style={styles.content}
              >
                <View
                  style={{ flex: 1, flexWrap: 'wrap', flexDirection: 'row' }}
                >

                      <Modal
                        transparent
                        animationType={'slide'}
                        visible={this.state.ModalVisibleStatus}
                      >
                          <View
                          style={{
                            flex: 1, backgroundColor: '#FFF'
                          }}
                          >
                          <View style={styles.navBar}>
                            <Text style={styles.navBarHeader}>Delivery Information</Text>
                            <TouchableOpacity
                              onPress={() => {
                                this.ShowModalFunction(!this.state.ModalVisibleStatus);
                                Keyboard.dismiss();
                              }}
                            >
                              <Text style={styles.navBarButton}>Done</Text>
                              </TouchableOpacity>
                              </View>
                          <KeyboardAvoidingView style={styles.login} behavior="padding">
                            <Block padding={[0, theme.sizes.base * 2]}>
                              <Block style={{ paddingVertical: 30 }}>
                                <Input
                                  label="Receiver's Name"
                                  text
                                  style={styles.input}
                                  onChangeText={this.handleChangeName}
                                  defaultValue={this.state.receiverName}
                                />
                                <Input
                                  label="Receiver's Phone no."
                                  phone
                                  style={styles.input}
                                  onChangeText={this.handleChangePhone}
                                  defaultValue={this.state.receiverPhone}
                                />
                                <View style={{ flex: 1 }}>

                                <Camera
                                />
                                </View>
                              </Block>
                            </Block>
                          </KeyboardAvoidingView>
                      </View>
                    </Modal>

                  <Block style={{ flex: 1, paddingRight: 100, backgroundColor: 'red' }}>
                    <View>{Where I want to preview the image}</View>
                  </Block>
                </View>
              </View>
            </View>
          );
        }
      }


      const styles = StyleSheet.create({
        input: {
          borderRadius: 0,
          borderWidth: 0,
          paddingTop: 0,
          borderBottomColor: theme.colors.gray2,
          borderBottomWidth: StyleSheet.hairlineWidth,
        },

        TextStyle: {
          fontSize: 20,
          marginBottom: 20,
          color: '#FFFFFF',
          padding: 20,
          textAlign: 'center'
        },
        navBar: {
        flexDirection: 'row',
        paddingTop: 35,
        height: 70,
        backgroundColor: '#34495E'
      },
        navBarButton: {
          color: '#FFFFFF',
          textAlign: 'center',
          width: 64
        },
        navBarHeader: {
          flex: 1,
          color: '#FFFFFF',
          fontWeight: 'bold',
          textAlign: 'center',
          fontSize: 16,
        },
      });

      export default Focal;

我希望按说明预览在View标签上单击完成按钮后拍摄的照片

2 个答案:

答案 0 :(得分:0)

您可以在索引中有一个函数,将图像作为参数并将其设置为setState,然后将此函数发送到以照片为道具的位置,然后在拍摄照片时使用它。

在“详细信息”类中:

// add this
handleNewPhoto = img => {
  this.setState({ image: img });
}

//and this
<Camera handleNewPhoto={this.handleNewPhoto} />

并在Camera类中:

takePicture = async () => {
          if (this.camera) {
            const photo = await this.camera.takePictureAsync({ base64: true });

            const formData = new FormData();
            formData.append('image', photo.base64);
            formData.append('type', 'base64');

            this.setState({
              latestImage: photo.uri,
              isCameraVisible: false
            });
            this.props.handleNewPhoto(photo.uri); // <---- add this
        }
        };

编辑:您可能还必须将其添加到details类构造器中

constructor(props) {
          super(props);
          this.state = {
            receiverName: '',
            receiverPhone: '',
            ModalVisibleStatus: false,

          };
   this.handleNewPhoto = this.handleNewPhoto.bind(this); // <---- this
        }

Edit2:

显示图像添加到视图中:

{this.state.image ? 
  <Image
      style={{width: width, height: height}}
      source={{uri: this.state.image}}
  /> : null 
}

答案 1 :(得分:-1)

有两种方法  1.如果您要使用react-navigation移至Details.js,则只需通过以下参数传递状态:     `this.props.navigation.navigate('details',{data:this.state}) 2.如果要在相机组件内部渲染细节组件,则可以像

<Deails {...this.props} {...this.state} />

像这样在Details.js中访问它:

<Image source={{uri:this.props.latestImage}} />