如果这个问题已在其他地方得到回答,我们深表歉意。是否有类型安全的方法将变体信息传递给子组件?
我正在尝试使用页面中描述的 useRestyle 挂钩创建自定义 Button 组件https://shopify.github.io/restyle/fundamentals/components/custom-components。我有这个代码:
const Button = ({
onPress,
label,
buttonType,
variant,
...rest
}: Props) => {
const props = useRestyle(restyleFunctions, {variant, ...rest});
我提取出了变体,但将其传递回 useRestyle,因为它需要第二个参数中的变体属性。但当我这样做时,我失去了类型安全性。
Eg: Button variant is 'primary' | 'secondary'. restyleFunctions shows the error:
The types of 'propertiesMap.variant' are incompatible between these types.
Type 'boolean | undefined' is not assignable to type 'boolean'.
Type 'undefined' is not assignable to type 'boolean'.ts(2345)
谢谢你。
我已经设法获得这样的值:
const {variant = 'primary'} = rest;
const props = useRestyle(restyleFunctions, rest)
必须传递默认值,因为变量是 Restyle 中的可选属性。
这是我使用shopify restyle 的自定义按钮的方式
import React from 'react';
import {
ActivityIndicator,
Pressable,
PressableProps,
TextStyle,
} from 'react-native';
import {BorderProps, ColorProps, createBox, useTheme} from '@shopify/restyle';
import {Text} from './Text';
import {Theme} from '../config/theme';
const BaseButton = createBox<Theme, PressableProps>(Pressable);
type Props = React.ComponentProps<typeof BaseButton> &
ColorProps<Theme> &
BorderProps<Theme> & {
label: string;
outline?: boolean;
loading?: boolean;
textStyle?: TextStyle;
textProps?: React.ComponentProps<typeof Text>;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
shadow?: boolean;
color?: any;
};
const Button = ({
label,
loading,
backgroundColor,
outline,
shadow = true,
color: textColor,
...props
}: Props) => {
const theme = useTheme<Theme>();
const color = outline ? backgroundColor : 'background';
const bgColor = outline ? 'background' : backgroundColor;
return (
<BaseButton
flexDirection="row"
backgroundColor={props.disabled ? 'gray400' : bgColor}
paddingHorizontal="xxl"
paddingVertical={{phoneSm: 'xxs', phone: 'xxxs'}}
borderRadius="s"
borderWidth={outline ? 0.5 : 0}
borderColor={props.disabled ? 'background' : color}
justifyContent="center"
alignItems="center"
shadowOffset={{
width: 0,
height: 1,
}}
shadowOpacity={shadow ? 0.22 : 0}
shadowRadius={2.22}
elevation={shadow ? 3 : 0}
{...props}
onPress={e => !loading && props.onPress && props.onPress(e)}>
{props.leftIcon && (
<Text color={color} marginRight="xxs">
{props.leftIcon}
</Text>
)}
<Text
variant="buttonLabel"
color={props.disabled ? 'background' : textColor ? textColor : color}
marginRight={loading ? 's' : undefined}
fontSize={{phoneSm: 14, phone: 16}}
{...props.textProps}>
{label}
</Text>
{/* {props.rightIcon && (
<Text color={color} marginLeft="xxs" {...props.textProps}>
{props.rightIcon}
</Text>
)} */}
{loading ? <ActivityIndicator color={theme.colors[color]} /> : null}
</BaseButton>
);
};
export default Button;