我目前正在玩和学习React的钩子。我想重新使用设置元素阴影的功能(使用bootstrap
作为css-framework)。
这是我的App
当前的样子:
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
悬停时添加阴影。不幸的是,悬停时什么也没发生,我不知道为什么。
在下面找到我的“自定义钩子”的实现:
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
钩子来设置元素的间距,其实现方式如下:
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];
}
并以这种方式使用:
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>
);
};
点击巨型机元素时,新间距将正确应用
答案 0 :(得分:1)
您的handleChange
函数正在返回另一个函数,删除第二个函数将对其进行修复。
const handleChange = (type: Type) => setShadow(type);