如何在 React Native Web 中自定义悬停?

问题描述 投票:0回答:1

在此反应本机 Web 组件中,我尝试自定义 TouchableRipple 效果以在悬停时添加绿色边框:

import React, { useState } from "react"
import { Pressable, View } from "react-native"
import { Surface, Text, TouchableRipple } from "react-native-paper"
import { colors } from "../../style/colors"

interface OptionItemMenuProps {
    section: {
        title: string
        data: {
            option: string
        }[]
    }[]
}

export const OptionItemMenu: React.FC<OptionItemMenuProps> = ({ section }) => {

    const [hover, setHover] = useState(false)

    return (
        <View>
            {section.map((option) => (
                <View key={option.title} style={{ gap: 2 }}>
                    <Text style={{ color: colors.grey, marginBottom: 5 }}>{option.title}</Text>
                    {option.data.map((item) => (
                        <TouchableRipple
                            key={item.option}
                            onPress={() => console.log("teste")}
                            onHoverIn={() => setHover(true)}
                            onHoverOut={() => setHover(false)}
                            style={[
                                { paddingVertical: 5, paddingLeft: 5, borderRadius: 5 },
                                hover && { borderColor: colors.primary, borderWidth: 1, paddingVertical: 4, paddingLeft: 4 },
                            ]}
                        >
                            <Text>{item.option}</Text>
                        </TouchableRipple>
                    ))}
                </View>
            ))}
        </View>
    )
}

但问题是,当我将悬停设置为 true 时,该样式将应用于地图列表中的所有项目,如下图所示:

不良行为的图像

我已经尝试过用事件控制悬停状态:

onHoverIn 和 onHoverOut; onPointerEnter 和 onPointerLeave;

如何单独自定义悬停?

css react-native onhover
1个回答
0
投票

我是这样解决的:

interface OptionItemMenuProps {
    section: {
        title: string
        data: {
            option: string
        }[]
    }[]
}

export const OptionItemMenu: React.FC<OptionItemMenuProps> = ({ section }) => {
    const [hoverStates, setHoverStates] = useState<{ [key: string]: boolean }>({})

    const handleMouseEnter = (key: string) => {
        setHoverStates((prev) => ({ ...prev, [key]: true }))
    }

    const handleMouseLeave = (key: string) => {
        setHoverStates((prev) => ({ ...prev, [key]: false }))
    }

    return (
        <View>
            {section.map((option) => (
                <View key={option.title} style={{ gap: 2 }}>
                    <Text style={{ color: colors.grey, marginBottom: 5 }}>{option.title}</Text>
                    {option.data.map((item) => (
                        <TouchableRipple
                            key={item.option}
                            onPress={() => console.log("teste")}
                            onHoverIn={() => handleMouseEnter(`${item.option}`)}
                            onHoverOut={() => handleMouseLeave(`${item.option}`)}
                            style={[
                                { paddingVertical: 5, paddingLeft: 5, borderRadius: 5 },
                                hoverStates[`${item.option}`] && { borderColor: colors.primary, borderWidth: 1, paddingVertical: 4, paddingLeft: 4 },
                            ]}
                        >
                            <Text>{item.option}</Text>
                        </TouchableRipple>
                    ))}
                </View>
            ))}
        </View>
    )
}

我创建了一个单独的控制状态:

const [hoverStates, setHoverStates] = useState<{ [key: string]: boolean }

通过这些函数,我可以控制每个项目的状态:

const handleMouseEnter = (key: string) => {
    setHoverStates((prev) => ({ ...prev, [key]: true }))
}

const handleMouseLeave = (key: string) => {
    setHoverStates((prev) => ({ ...prev, [key]: false }))
}

这里我改变状态:

onHoverIn={() => handleMouseEnter(`${item.option}`)}
onHoverOut={() => handleMouseLeave(`${item.option}`)}

在这里我相应地检查状态和样式:

hoverStates[`${item.option}`] && { borderColor: colors.primary, borderWidth: 1, paddingVertical: 4, paddingLeft: 4 },

这就是我设法解决它的方法,但如果有人知道如何以其他方式解决它,请随时发布在这里

© www.soinside.com 2019 - 2024. All rights reserved.