可压样式不适用于原生风

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

我将

react-native
nativewind
库一起使用,并且
Pressable
中的条件样式在包含在带有
View
类名的
nativewind
中时不起作用。
因此,基本上从包装器
className
中删除
View
使
Pressable
样式工作(背景颜色切换)。
为什么会发生这种情况? :(

     <View className="flex-row basis-8/12 gap-x-2">
          <Pressable
            style={({ pressed }) => [
              {
                backgroundColor: pressed ? 'black' : 'white',
              },
            ]}>
            <Text>Select</Text>
          </Pressable>
        </View>
react-native tailwind-css native nativewind
1个回答
0
投票

我已经实现了一种使用状态管理来处理按下状态并应用条件样式的解决方法。我们将使用 cn 函数 (utils/cn.ts):

import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
    return twMerge(clsx(inputs));
}

现在您可以更新组件 (ActionButton.tsx) 以使用 useState 挂钩来管理按下状态并使用 cn 有条件地应用样式:

import { useState } from "react";
import { Pressable, Text } from "react-native";
import { cn } from "@/utils/cn";

export default function MyComponent() {
    const [isPressed, setPressed] = useState(false);

    return (
        <View className="flex-row basis-8/12 gap-x-2">
            <Pressable
                onPressIn={() => setPressed(true)}
                onPressOut={() => setPressed(false)}
                className={cn(
                    "items-center justify-center rounded-md p-3",
                    isPressed ? "bg-black" : "bg-white"
                )}
            >
                <Text>Select</Text>
            </Pressable>
        </View>
    );
}

但这迫使您为布局上的每个可按按钮使用状态。这是一个简单的组件(CustomPressable.tsx),可以帮助您避免这种情况:

import React, { useState } from "react";
import { Pressable, StyleProp, ViewStyle } from "react-native";

interface CustomPressableProps {
    className: (isPressed: boolean) => string;
    children: React.ReactNode | ((isPressed: boolean) => React.ReactNode);
    onPress?: () => void;
    onPressIn?: () => void;
    onPressOut?: () => void;
    style?: StyleProp<ViewStyle>;
}

export function CustomPressable({
    className,
    style,
    children,
    onPress,
    onPressIn,
    onPressOut,
}: CustomPressableProps) {
    const [isPressed, setPressed] = useState(false);

    return (
        <Pressable
            onPress={onPress}
            onPressIn={() => {
                onPressIn && onPressIn();
                setPressed(true);
            }}
            onPressOut={() => {
                onPressOut && onPressOut();
                setPressed(false);
            }}
            className={className(isPressed)}
            style={style}
        >
            {typeof children === "function" ? children(isPressed) : children}
        </Pressable>
    );
}

这是一个使用示例(ActionButton.tsx):

import React from "react";
import { Svg } from "react-native-svg";
import colors from "tailwindcss/colors";

import { CustomPressable } from "@/components/CustomPressable";
import { cn } from "@/utils/cn";

export function ActionButton({
    iconComponent,
    buttonSize,
    iconScale = 1,
}: {
    iconComponent: React.ReactElement;
    buttonSize: number;
    iconScale?: number;
}) {
    const scaledSize = buttonSize * iconScale;

    return (
        <CustomPressable
            style={{
                width: buttonSize,
                height: buttonSize,
            }}
            className={(isPressed) =>
                cn(
                    "items-center justify-center rounded-xl",
                    isPressed ? "bg-accent" : "bg-gray-200",
                )
            }
        >
            {(isPressed) => (
                <Svg
                    width={scaledSize}
                    height={scaledSize}
                    viewBox="0 0 24 24"
                    color={isPressed ? "white" : colors.violet["800"]}
                >
                    {iconComponent}
                </Svg>
            )}
        </CustomPressable>
    );
}

如果有人制作了一个与 Pressable 具有相同属性的组件 - 请与我分享 ^^

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