Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native "onPress is not a function" when passing function in Modal

I'm trying to have a Modal visible flag turn false when a button within the modal is pressed. I was able to get the modal to become visible when pushing a button on the screen. However, when I use similar code to make is not visible I get the following error:

TypeError: onPress is not a function. (In 'onPress(event)', 'onPress' is an instance of Object)

I believe the problem lies in <CreatorModal onPressClose={() => setCreatorModalVisible(false)} /> and <TouchableOpacity onPress={onPressClose}>

I'm very new to Javascript, React and React Native so I'm very lost Would someone please help me figure out why this is happening and also provide a solution?

I have attached my code below:

videoCard.js

import React, { useState } from "react";

import { useWindowDimensions, Modal } from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import style from "styled-components/native";

import Colors from "./colors";
import VideoPlayer from "./videoPlayer";
import VideoElements from "./videoElements";
import CreatorModal from "./creatorModal";

const Gradient = style((props) => <LinearGradient {...props} />)`
    height: 100%;
    width: 100%;
    justifyContent: center;
    alignItems: flex-end;
    position: absolute;
    top: 0;
    left: 0;
    zIndex: 1;
`;

const VideoContainer = style.View`
    backgroundColor: ${Colors.darkGrey};
    justifyContent: center;
    alignItems: flex-end;
`;

const VideoCard = ({ card, isPlay }) => {
    const [creatorModalVisible, setCreatorModalVisible] = useState(false);

    const width = useWindowDimensions().width;
    const height = useWindowDimensions().height;

    return (
        <VideoContainer style={{ height: height, width: width }}>
            <Modal
                animationType="slide"
                transparent={true}
                visible={creatorModalVisible}
            >
                <CreatorModal
                    onPressClose={() => setCreatorModalVisible(false)}
                />
            </Modal>
            <VideoPlayer
                video={card.video.video}
                isPlay={isPlay}
                orientation={card.video.orientation}
            />
            <Gradient
                locations={[0, 0.25, 0.75, 1]}
                colors={[
                    "rgba(35,35,35,1)",
                    "rgba(35,35,35,0)",
                    "rgba(35,35,35,0)",
                    "rgba(35,35,35,1)",
                ]}
            >
                <VideoElements
                    creator={card.creator}
                    product={card.product}
                    brand={card.brand}
                    onPressCreator={() => setCreatorModalVisible(true)}
                />
            </Gradient>
        </VideoContainer>
    );
};

export default VideoCard;

videoElements.js

import React from "react";

import { Image, Text, View, Modal } from "react-native";
import style from "styled-components/native";
import { Feather } from "@expo/vector-icons";

import Colors from "./colors";

const Container = style.View`
    flexDirection: row;
    justifyContent: space-between;
    alignItems: flex-end;
    width: 100%;
    height: 100%
`;

const LeftContainer = style.View`
    flexDirection: column;
    justifyContent: flex-end;
    width: 50%;
    left: 1%;
    bottom: 10%;
`;

const RightContainer = style.View`
    flexDirection: column;
    justifyContent: flex-end;
    alignItems: center;
    width: 20%;
    right: 1%;
    bottom: 10%;
`;

const Element = style.TouchableOpacity`
    flexDirection: column;
    justifyContent: center;
    alignItems: center;
    height: 45px;
    shadowColor: ${Colors.darkGrey};
    shadowOpacity: 1;
    shadowRadius: 10px;
`;

const BasicText = style.Text`
    font-size: 12px
    fontFamily: Helvetica;
    color: ${Colors.white};
    textShadowRadius: 1px;
    textShadowColor: ${Colors.darkGrey};
`;

const BigBoldText = style(BasicText)`
    font-size: 15px;
    fontWeight: bold;
`;

const ElementText = style(BasicText)`
    font-size: 10px;
    fontWeight: bold;
`;

const VideoElements = ({ creator, product, brand, onPressCreator }) => {
    return (
        <Container>
            <LeftContainer>
                <BasicText>{brand.name}</BasicText>
                <BigBoldText>{product.name}</BigBoldText>
                <BasicText>$ {product.price}</BasicText>
            </LeftContainer>
            <RightContainer>
                {creator !== undefined && (
                    <Element onPress={onPressCreator}>
                        <Feather name="user" size={20} color="white" />
                        <ElementText>@{creator.username}</ElementText>
                    </Element>
                )}
                <Element>
                    <Feather name="arrow-up-circle" size={20} color="white" />
                    <ElementText>Product</ElementText>
                </Element>
            </RightContainer>
        </Container>
    );
};

export default VideoElements;

creatorModal.js

import React, { useState } from "react";

import { Image, Text, View, TouchableOpacity } from "react-native";
import style from "styled-components/native";

import Colors from "./colors";

const Container = style.View`
    flexDirection: column;
    justifyContent: center;
    alignItems: center;
    width: 100%;
    height: 100%;
`;

const ModalContainer = style.View`
    backgroundColor: ${Colors.white};
    width: 100%;
    height: 40%;
`;

const creatorModal = (onPressClose) => {
    return (
        <Container>
            <ModalContainer>
                <Text>Creator</Text>
                <TouchableOpacity onPress={onPressClose}>
                    <Text>Close</Text>
                </TouchableOpacity>
            </ModalContainer>
        </Container>
    );
};

export default creatorModal;
like image 902
ev-h Avatar asked May 07 '26 17:05

ev-h


1 Answers

Small sample app output using your creatorModal source code after passing onPressClose as an object:

enter image description here

const creatorModal = ({onPressClose}) => {
//pass object here ______^^^^^^^^^    
return (
        <Container>
            <ModalContainer>
                <Text>Creator</Text>
                <TouchableOpacity onPress={onPressClose}>
                    <Text>Close</Text>
                </TouchableOpacity>
            </ModalContainer>
        </Container>
    );
};

export default creatorModal;

Here is the working example: Expo Snack

Or, you can keep creatorModal.js as it is and make the following changes to videoCard.js:

<Modal
    animationType="slide"
    transparent={true}
    visible={creatorModalVisible}>
        {CreatorModal(() => setCreatorModalVisible(false))}
        //call it as a simple function ____^^^^^^^^^^^^^^^
 </Modal>
like image 171
Ketan Ramteke Avatar answered May 09 '26 06:05

Ketan Ramteke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!