首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于动态设置css类的自定义react-hook

用于动态设置css类的自定义react-hook
EN

Stack Overflow用户
提问于 2019-06-27 22:29:45
回答 1查看 719关注 0票数 0

我现在正在学习React的钩子。我想重用设置元素阴影的功能(使用bootstrap作为css框架)。

这是我的App当前的样子:

代码语言:javascript
复制
export const App: React.FunctionComponent<IAppProps> = ({ }: IAppProps) => {
    // get shadow-classes for alert
    const [shadowClasses, setShadowClasses] = useShadow("none");

    // define callbacks when hovering the alert
    const handleMouseEnter = () => setShadowClasses("regular");
    const handleMouseOut = () => setShadowClasses("none");

    // return the markup to be used
    return (
        <Container>
            <Grid.Row>
                <Grid.Col>
                    <Alert color={Constants.Color.Danger} className={classNames(shadowClasses)} onMouseEnter={handleMouseEnter} onMouseOut={handleMouseOut} >{"This is some kind of an alert ..."}</Alert>
                </Grid.Col>
            </Grid.Row>
        </Container>
    );
}; 

我的目标是在Alert悬停时添加阴影。不幸的是,在悬停的时候什么都没有发生,我也不明白为什么。

下面是我的“自定义钩子”的实现:

代码语言:javascript
复制
export function useShadow(initialType: "none"|"sm"|"regular"|"large"): [string[], (type: "none"|"sm"|"regular"|"large") => void] {
    // define the classes to be used
    const classNames: string[] = [];

    // get the shadow's current value
    const [shadowType, setShadow] = React.useState(initialType);

    // set depending on given type
    switch (shadowType) {
        case "none":
            classNames.push(`shadow-none`);
            break;
        case Constants.BreakpointSize.Small:
            classNames.push(`shadow-sm`);
            break;
        case "regular":
            classNames.push(`shadow`);
            break;
        case Constants.BreakpointSize.Large:
            classNames.push(`shadow-lg`);
            break;
    }

    // define the callback to change the shadow
    const handleChange = (type: Type) => () => setShadow(type);

    // return the class-names and the change-callback
    return [classNames, handleChange];
}

我甚至不确定这是不是使用自定义钩子的正确方法。

**更新**

我创建了一个useSpacing钩子来设置元素的间距,其实现方式如下:

代码语言:javascript
复制
export function useSpacing(initialSpacingProps: ISpacingProps[] = []): [string[], (spacingProps: ISpacingProps[]) => void] {
    // get the state-value
    const [spacingProps, setSpacingProps] = React.useState(initialSpacingProps);

    // create the result holding the class-names
    const spacingClasses: string[] = [];

    // loop through given spacing-definitions
    for (let spacingProp of spacingProps) {
        // get the values
        const { breakpoint, property, side, size, negative } = spacingProp;

        // handle depending on breakpoint
        spacingClasses.push(`${property}${side}${breakpoint !== Constants.BreakpointSize.ExtraSmall ? `-${breakpoint}` : ``}-${negative && size !== Size.Auto ? `n` : ``}${size}`);
    }

    // define the callback when the value should be changed
    const handleChange = (newSpacingProps: ISpacingProps[]) => setSpacingProps(newSpacingProps);

    // return the classes
    return [spacingClasses, handleChange];
}

并以这种方式使用:

代码语言:javascript
复制
export const App: React.FunctionComponent<IAppProps> = ({ }: IAppProps) => {
    const initialSpacingProps = [
        {
            breakpoint: Constants.BreakpointSize.ExtraSmall,
            property: Spacing.Property.Margin,
            side: Spacing.Side.LeftRight,
            size: Spacing.Size.Two
        }
    ];

    const clickedSpacingProps = [
        {
            breakpoint: Constants.BreakpointSize.Small,
            property: Spacing.Property.Padding,
            side: Spacing.Side.TopBottom,
            size: Spacing.Size.Five
        }
    ];

    // get the classes to apply spacing accordingly
    const [spacingClasses, setSpacingClasses] = useSpacing(initialSpacingProps);

    // define the callback when jumbotron gets clicked
    const handleClick = React.useCallback(() => setSpacingClasses(clickedSpacingProps), []);

    // return the markup to be used
    return (
        <Container>
            <Grid.Row>
                <Grid.Col>
                    <Shadows.Shadow type={Constants.BreakpointSize.Large}>
                        <Jumbotron className={classNames(spacingClasses)} onClick={handleClick}>
                            <h1 className="display-4">Hello, world!</h1>
                        </Jumbotron>
                    </Shadows.Shadow>
                </Grid.Col>
            </Grid.Row>
        </Container>
    );
};

单击jumbotron-element时,将正确应用新间距

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-27 23:38:51

您的handleChange函数正在返回另一个函数,删除第二个函数将修复此问题。

代码语言:javascript
复制
const handleChange = (type: Type) => setShadow(type);

演示:https://codesandbox.io/s/youthful-gould-offv6

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56793292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档