Home > Back-end >  How can I pass the current item to a component in react-native?
How can I pass the current item to a component in react-native?

Time:09-28

I'm trying to pass the currently clicked item to the React-Native's own Modal component with props, but without success. Now it will only show the same item in all the modals regardless of what item was pressed.

Homepage that renders content and passes the data for Modal component:

<HomepageDataView>
    {habitData !== null &&
        Object.values(habitData).map((item, index) => (
            <HomepageDataBox
                key={index.toString()}
                onPress={() => {
                    setModalVisible(true);
                    haptics.selection();
                }}
                style={{ borderBottomWidth: 7, borderBottomColor: `${item.color}` }}
            >
                <Image style={{ height: 50, width: 50 }} source={item.icon} />
                <Text fontFamily="SemiBold" marginLeft="5px">
                    {item.name}
                </Text>

                <ShowHabitModal
                    data={item}
                    modalVisible={modalVisible}
                    setModalVisible={setModalVisible}
                />
            </HomepageDataBox>
        ))}
</HomepageDataView>

Modal component:

 export default function ShowHabitModal({ modalVisible, setModalVisible, data }) {
    return (
        <Modal animationType="slide" presentationStyle="pageSheet" visible={modalVisible}>
            <ModalContent>
                <HomeheaderContainer>
                    <TouchableOpacity
                        style={{ marginLeft: 10, marginTop: 10 }}
                        onPress={() => setModalVisible(false)}
                    >
                        <Ionicons name="close-circle-sharp" size={34} color="gray" />
                    </TouchableOpacity>
                    <TouchableOpacity>
                        <Text marginRight="15px" color={colors.mainGreen} fontFamily="SemiBold">
                            Edit
                        </Text>
                    </TouchableOpacity>
                </HomeheaderContainer>
                <ShowHabitDataContainer>
                    <View style={showHabitImageBackground}>
                        <Image style={{ width: 90, height: 90 }} source={data.icon} />
                    </View>
                    {data.description !== '' && <Text>{data.description}</Text>}
                    <Text fontFamily="SemiBold" marginTop="15px" twentyEight>
                        {data.name}
                    </Text>
                    <Text>{data.days}</Text>
                    <Text>{data.times}</Text>
                </ShowHabitDataContainer>
            </ModalContent>
        </Modal>
    );
}

CodePudding user response:

Kuncheria is right. You have few modals open at the same time.

If you need to create few modals, try something like this:

const HomePage = () => {
    const [visibleItem, setVisibleItem] = useState();

    return <HomepageDataView>
        {habitData !== null && Object.values(habitData).map((item, index) => {
            const id = index.toString();
            return (
                <HomepageDataBox
                    key={id}
                    onPress={() => {
                        setVisibleItem(id);
                        haptics.selection();
                    }}
                    style={{ borderBottomWidth: 7, borderBottomColor: `${item.color}` }}
                >
                    <Image style={{ height: 50, width: 50 }} source={item.icon} />
                    <Text fontFamily="SemiBold" marginLeft="5px">
                        {item.name}
                    </Text>

                    <ShowHabitModal
                        data={item}
                        modalVisible={visibleItem === id}
                        setModalVisible={setVisibleItem}
                    />
                </HomepageDataBox>
            );      
        })}
    </HomepageDataView>
};

const ShowHabitModal = ({ modalVisible, setModalVisible, data }) => (
    <Modal animationType="slide" presentationStyle="pageSheet" visible={modalVisible}>
        <ModalContent>
            <HomeheaderContainer>
                <TouchableOpacity
                    style={{ marginLeft: 10, marginTop: 10 }}
                    onPress={() => setModalVisible(false)}
                >
                    <Ionicons name="close-circle-sharp" size={34} color="gray" />
                </TouchableOpacity>
                <TouchableOpacity>
                    <Text marginRight="15px" color={colors.mainGreen} fontFamily="SemiBold">
                        Edit
                    </Text>
                </TouchableOpacity>
            </HomeheaderContainer>
            <ShowHabitDataContainer>
                <View style={showHabitImageBackground}>
                    <Image style={{ width: 90, height: 90 }} source={data.icon} />
                </View>
                {data.description !== '' && <Text>{data.description}</Text>}
                <Text fontFamily="SemiBold" marginTop="15px" twentyEight>
                    {data.name}
                </Text>
                <Text>{data.days}</Text>
                <Text>{data.times}</Text>
            </ShowHabitDataContainer>
        </ModalContent>
    </Modal>
);

If you can use a single modal, then try something like this:

const HomePage = () => {
    const [modalVisible, setModalVisible] = useState();
    const [visibleItem, setVisibleItem] = useState();

    return <HomepageDataView>
        {habitData !== null && Object.values(habitData).map((item, index) => {
            const id = index.toString();
            return (
                <HomepageDataBox
                    key={id}
                    onPress={() => {
                        setVisibleItem(item);
                        setModalVisible(true);
                        haptics.selection();
                    }}
                    style={{ borderBottomWidth: 7, borderBottomColor: `${item.color}` }}
                >
                    <Image style={{ height: 50, width: 50 }} source={item.icon} />
                    <Text fontFamily="SemiBold" marginLeft="5px">
                        {item.name}
                    </Text>
                </HomepageDataBox>
            );      
        })}
        <ShowHabitModal
            data={visibleItem}
            modalVisible={modalVisible}
            setModalVisible={setModalVisible}
        />
    </HomepageDataView>
};

const ShowHabitModal = ({ modalVisible, setModalVisible, data }) => (
    <Modal animationType="slide" presentationStyle="pageSheet" visible={modalVisible}>
        <ModalContent>
            <HomeheaderContainer>
                <TouchableOpacity
                    style={{ marginLeft: 10, marginTop: 10 }}
                    onPress={() => setModalVisible(false)}
                >
                    <Ionicons name="close-circle-sharp" size={34} color="gray" />
                </TouchableOpacity>
                <TouchableOpacity>
                    <Text marginRight="15px" color={colors.mainGreen} fontFamily="SemiBold">
                        Edit
                    </Text>
                </TouchableOpacity>
            </HomeheaderContainer>
            <ShowHabitDataContainer>
                <View style={showHabitImageBackground}>
                    <Image style={{ width: 90, height: 90 }} source={data.icon} />
                </View>
                {data.description !== '' && <Text>{data.description}</Text>}
                <Text fontFamily="SemiBold" marginTop="15px" twentyEight>
                    {data.name}
                </Text>
                <Text>{data.days}</Text>
                <Text>{data.times}</Text>
            </ShowHabitDataContainer>
        </ModalContent>
    </Modal>
);
  • Related