0

I am a newbie in react native, I am developing a video app to aid my learning curve. In the code below I have tried all I could to solve the error on the "displayModal" line, but could not. Please can anyone help me with this. I want on image/video capture it will display on the modal and from the modal i will be able to "Discard", or "Save"(to firebase), or "Share" the image/video.

import React from 'react';
import { View, Text, Image, Modal, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

import styles from './styles';

export default ({captures=[]}) => {
   state = {
   isVisible: false
   }
 // hide show modal
  displayModal(show){  ------this is where am getting the error
   this.setState({isVisible: show})
}
 return (

  <Modal 
   transparent={true}
   visible={this.state.isVisible}
   // style={[styles.bottomToolbar, styles.galleryContainer]} 
>
 <View style={{backgroundColor: "#000000aa", flex: 1}}>
  {captures.map(({ uri }) => (
  <View style={styles.galleryImageContainer} key={uri}>
   <Image source={{ uri }} style={styles.galleryImage} />
  </View>
 ))}
 </View>
 <TouchableOpacity style={{justifyContent: 'center', alignItems: 'center'}}>
 <Ionicons
  name="close-outline"
  color="white"
  size={20}
  onPress={() => {this.displayModal(!this.state.isVisible);}}
  />
   <Text>Discard</Text>
   </TouchableOpacity>
   </Modal>

  );
};

click here to see error image

Benjamin Ikwuagwu
  • 377
  • 1
  • 9
  • 28

2 Answers2

1

From you code it looks like a functional component, but you are using state as class-based component, that might be the reason you are getting error :

export default ({captures=[]}) => {
  state = {
    isVisible: false
  }
  // hide show modal
  displayModal(show){  ------this is where am getting the error
    this.setState({isVisible: show})
  }

Above code block should look like this :

export default ({captures=[]}) => {

  const [state,setState] = useState({ isVisible: false })

  // hide show modal
  const displayModal = (show) => { 
    setState({isVisible: show})
  }
Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
0

You are mixing functional component with class component. "this.state" and "this.setState" belong to class components and all the rest belongs to functional components.

Try to change this:

state = {
   isVisible: false
   }
 // hide show modal
  displayModal(show){  ------this is where am getting the error
   this.setState({isVisible: show})
}

To this:

const [isVisible, setIsVisible] = React.useState(false);

const displayModal = show => setIsVisible(show);

In addition, in the return statement, remove the strings/words "this" and "this.state".

Requested addition:

import React, { useState } from 'react';
import { View, Text, Image, Button, Modal, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { storage } from './fbstorage';
import { Camera } from 'expo-camera';

import styles from './styles';

export default ({ captures = [] }) => {
    const [isVisible, setIsVisible] = useState(false);

    const takePicture = async () => {
        const photoData = await Camera.takePictureAsync();
        if (!photoData.cancelled) {
            uploadImage(photoData.uri, imageName)
                .then(() => {
                    Alert.alert("Success");
                })
                .catch((error) => {
                    Alert.alert('Error:', error.message);
                });
        }
    }

    const uploadImage = async (uri, imageName) => {
        const response = await fetch(uri);
        const blob = await response.blob();
        var ref = storage().ref().child("images/" + imageName);
        return ref.put(blob)
    }

    return (
        <Modal
            transparent={true}
            visible={isVisible}
        // style={[styles.bottomToolbar, styles.galleryContainer]} 
        >
            <View style={{ backgroundColor: "#000000aa", flex: 1 }}>
                {captures.map(({ uri }) => (
                    <View style={styles.galleryImageContainer} key={uri}>
                        <Image source={{ uri }} style={styles.galleryImage} />
                    </View>
                ))}
            </View>
            <TouchableOpacity
                style={{
                    justifyContent: 'center',
                    alignItems: 'center',
                    marginTop: 20,
                    top: -20
                }}
                onPress={() => setIsVisible(false)}
            >
                <Ionicons
                    name="md-reverse-camera"
                    color="white"
                    size={40}
                />
                <Text style={{ color: 'white' }}>Discard</Text>
            </TouchableOpacity>
            <Button
                title='Save'
                onPress={takePicture}
            />
        </Modal>
    );
};
D10S
  • 1,468
  • 2
  • 7
  • 13
  • Hi, thanks for your response...I've removed the strings "this" and "this.state" but I still could not close the modal when I tap the icon/Discard button. I set visible={true}, then onPress={() => {displayModal(false)}} how do I correct it – Benjamin Ikwuagwu Jun 17 '20 at 18:42
  • On the "Ionicons" close icon set onPress like this: onPress={() => setIsVisible(false)} – D10S Jun 17 '20 at 20:30
  • I have tried it but It didn't work...its not closing the modal – Benjamin Ikwuagwu Jun 17 '20 at 20:35
  • Without seeing the whole code it will be impossible to help – D10S Jun 18 '20 at 04:57
  • Thank you @D10S I have uploaded the project on github---this is the link for the file -- https://github.com/wiredmatrix/vocvedo/blob/master/src/gallery.component.js Link for whole project --- https://github.com/wiredmatrix/vocvedo please reply your help here...thanks so much – Benjamin Ikwuagwu Jun 18 '20 at 10:20
  • So: (1) You import 'storage' but never use it (2) remove all "this." (3) you call 'camera' but never decalred a variable with name 'camera' nor imported it. Same goes with 'firebase' (4) the 'if' statement should be inside a 'useEffect' (5) 'displayModal' function is useless at it does exactly what 'setIsVisible' does (6) You never use 'isVisible' so calling 'setIsVisible' gives you nothing. And accordingly the modal visibility is set to 'true' so it will always be visible (7) according to the 'captures.map' captures is an array of objects which has a field called 'uri'. is it? – D10S Jun 19 '20 at 07:50
  • Yes, please can you help post with the right code...am lost on how to apply with the right code here...have been on this for days now...still learning – Benjamin Ikwuagwu Jun 20 '20 at 05:05
  • I know how it feels so I add the code as I think will work. See the bottom part of my answer (th 'Requested addition' part) – D10S Jun 20 '20 at 08:24