【问题标题】:Pass a particular state in one component to another将一个组件中的特定状态传递给另一个组件
【发布时间】:2019-06-04 12:31:21
【问题描述】:

我正在开发一个需要用户拍照的应用程序,我已经能够处理相机组件,但是我不知道如何将拍摄的图像传递到相机组件所在的另一个组件屏幕被进口。 下面是相机组件,我想在哪里传递相机组件的新状态。

我还没有真正尝试过任何具体的东西,因为我不知道我是否应该传递状态或道具。

相机组件

      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 标签上的完成按钮后拍摄的照片

【问题讨论】:

  • 如果您将图像存储在状态中,为什么不简单地将状态(或您需要的条目)作为道具传递?
  • 你能解释一下我是如何做到这一点的吗,我已经尝试了我知道的 hacky 方法,但显然它们不起作用。如果您能指导我,将不胜感激。

标签: javascript reactjs react-native state expo


【解决方案1】:

您可以在 index 中有一个函数,将图像作为参数并对其进行 setState,并将此函数发送到您将照片作为道具的地方,然后在您拍照时使用它。

在详细信息类中:

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

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

在相机类中:

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
        }
        };

编辑:您可能还需要将此添加到详细信息类构造函数中

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

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

编辑2:

在视图中添加显示图像:

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

【讨论】:

  • 如何在 Detail 类的底部 View 标签中传递或预览它?
  • 如你所见,我在模态标签中渲染了相机组件以及文本输入,我想在“{我要预览图像的地方}onPress 完成文本按钮
  • 比你这么多,你刚刚救了我。我是本地人的新手,我真的很高兴有人在学习过程中向我展示绳索
  • 不客气,兄弟,我很乐意提供帮助。如果您遇到无法在此处找到答案的问题,请在推特上添加我@linkinmedo,如果可以,我会为您提供帮助。
  • 你一直很友善,但我不在推特上,我希望我能收到你的电子邮件,或者可能是脸书
【解决方案2】:

有两种方法可以做到这一点 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}} />

【讨论】:

  • 我认为您在 #2 处遗漏了一些代码,请相应地进行编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 2020-03-12
  • 2017-11-07
  • 2016-12-05
  • 1970-01-01
  • 2019-05-30
  • 2021-01-11
相关资源
最近更新 更多