[英]Custom react-hook for dynamically setting css-classes
我目前正在玩和學習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>
);
};
單擊巨型機元素時,正確應用了新的間距
您的handleChange
函數將返回另一個函數,刪除第二個函數將對其進行修復。
const handleChange = (type: Type) => setShadow(type);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.