简体   繁体   English

在 Modal 中传递 function 时 React Native “onPress 不是函数”

[英]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.类型错误:onPress 不是 function。 (In 'onPress(event)', 'onPress' is an instance of Object) (在 'onPress(event)' 中,'onPress' 是 Object 的一个实例)

I believe the problem lies in <CreatorModal onPressClose={() => setCreatorModalVisible(false)} /> and <TouchableOpacity onPress={onPressClose}>我相信问题出在<CreatorModal onPressClose={() => setCreatorModalVisible(false)} /><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?我对 Javascript、React 和 React Native 很陌生,所以我很迷茫有人请帮我弄清楚为什么会这样并提供解决方案吗?

I have attached my code below:我在下面附上了我的代码:

videoCard.js显卡.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视频元素.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 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;

Small sample app output using your creatorModal source code after passing onPressClose as an object:在将onPressClose作为 object 传递后,使用您的creatorModal源代码的小示例应用程序 output:

在此处输入图像描述

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这是工作示例: Expo Snack

Or, you can keep creatorModal.js as it is and make the following changes to videoCard.js :或者,您可以保持creatorModal.js原样,并对videoCard.js进行以下更改:

<Modal
    animationType="slide"
    transparent={true}
    visible={creatorModalVisible}>
        {CreatorModal(() => setCreatorModalVisible(false))}
        //call it as a simple function ____^^^^^^^^^^^^^^^
 </Modal>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM