Я сейчас играю и изучаю хиты 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>
);
};
При нажатии на элемент jumbotron новый интервал применяется правильно