Home > Software design >  Passing the current item to a component in react-native
Passing the current item to a component in react-native

Time:09-27

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. Any advice highly appreciated!

Current code:

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