styled-components - 子组件功能不更新 DOM
问题描述
我有两个使用样式组件构建的组件,一个父组件和一个子组件。父组件将一些道具传递给子组件。如果需要,我可以添加样式,但我认为它们与我的问题无关。
家长
export const NavigationWrapper = ({ ariaLabel, expanded }) => {
const [active, setActive] = React.useState(null);
return (
<NavWrapper
aria-label={ariaLabel}
data-testid="nav-wrapper"
expanded={expanded}
>
<HeaderNavTab expanded={expanded} data-testid="header-nav-tab" href="/">
</HeaderNavTab>
<NavBodyTab
text="Dashboard"
Icon={Grid}
expanded={expanded}
active={active}
setActive={setActive}
/>
<NavBodyTab
text="People"
Icon={People}
expanded={expanded}
active={active}
setActive={setActive}
subNavMenu={[
{ name: "Link1" },
{ name: "Link2", subnav: ["sub link 1", "sub link 2"] },
]}
/>
<NavBottomSpace data-testid="bottom-space" expanded={expanded} />
</NavWrapper>
);
};
子组件从父组件获取道具,并且它也有自己的钩子状态。
孩子
export const NavBodyTab = ({
expanded,
text,
Icon,
subNavMenu,
active,
setActive,
}) => {
const [hovered, setHovered] = React.useState(false);
const [opened, setOpened] = React.useState(null);
const [subNavActive, setSubNavActive] = React.useState(null);
const [subNavOpen, setSubNavOpen] = React.useState(false);
const [subNavHovered, setSubNavHovered] = React.useState(false);
const setActiveTab = (text) => {
if (active === text) {
setActive(null);
} else {
setActive(text);
}
};
const setOpenTab = (text) => {
if (opened === text) {
setOpened(null);
} else {
setOpened(text);
}
};
return (
<div>
<NavTab
expanded={expanded}
opened={opened}
hovered={hovered}
active={active}
text={text}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
onFocus={() => {
setActiveTab(text);
}}
onBlur={() => {
setActiveFunction(subNavMenu);
}}
onClick={() => setOpenTab(text)}
onKeyDown={handleKeyPress}
data-testid={text + "-nav-tab"}
tabIndex="0"
>
{expanded || (hovered && active === null) || active === text ? (
<div>
<IconHolder
expanded={expanded}
hovered={hovered}
text={text}
active={active}
data-testid={text + "-icon-holder"}
>
<Icon
fill={
hovered || active === text ? `${basic[100]}` : `${basic[500]}`
}
stroke={
hovered || active === text ? `${basic[100]}` : `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
</IconHolder>
{text}
{expanded || subNavMenu ? (
<ArrowHolder data-testid={text + "-arrow-holder"}>
{opened === text && subNavMenu && expanded ? (
<ArrowDownward
data-testid={text + "-arrow-icon-down"}
fill={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
stroke={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
) : (
<ArrowForward
data-testid={text + "-arrow-icon"}
fill={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
stroke={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
)}
</ArrowHolder>
) : null}
</div>
) : (
<div>
<IconHolder>
<Icon
fill={`${basic[500]}`}
stroke={`${basic[500]}`}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
</IconHolder>
</div>
)}
</NavTab>
</div>
);
};
我在这里剪掉了很多绒毛,但这是基本想法。现在我正在尝试纠正一个测试,该测试将检查 navTab 样式是否正确更新。
我在 navTab 上有一些样式:
const NavTab = styled.div`
height: 3.5rem;
${(props) =>
props.hovered && props.active === null
? `width: 16.25rem; color: ${basic[100]};`
: null}
${(props) =>
props.active === props.text
? `width: 16.25rem; background-color: #434e59; color: ${basic[100]}; outline: none;`
: null}
`;
当用户将鼠标悬停在 NavTab 上时,我应该能够测试样式是否发生了变化。
test("mouse over", () => {
const expanded = false;
const setExpanded = jest.fn();
React.useState = jest.fn(() => [expanded, setExpanded]);
const { getByTestId, queryByTestId, debug } = render(
<NavigationWrapper
ariaLabel="navigation wrapper"
expanded={false}
/>
);
const navTab = getByTestId("People-nav-tab");
expect(navTab).toHaveStyleRule("width", "5rem");
fireEvent.mouseEnter(navTab);
expect(navTab).toHaveStyleRule("width", "16.25rem");
});
最后一次测试失败。我曾尝试使用debug()
来查看 navTab 组件如何随悬停而变化,但没有任何变化。我还使用调试来查看 navTab 如何随着焦点的变化也没有变化。我也尝试过fireEvent
单击 navTab 并且再次没有更改调试器输出。
我真的很困惑我应该如何测试这些风格和状态的变化。
解决方案
推荐阅读
- python - 在不使用枚举的情况下查找匹配模式的行号
- ios - 我如何在 Swift 3 中处理字典
- php - gcloud sql连接不起作用
- ios - IOS如何在swift中获取多个String.range(of:string)
- java - Lucene 6.2.1 如何在不知道其名称的情况下获取所有字段名称或搜索所有字段
- javascript - 更改数据源时Angularjs Devextreme组件不刷新
- php - 在特定位置的多维数组中插入新键值
- serverless-framework - 使用 serverless-dotenv-plugin 更正 .env 文件
- linux - 如何删除 2017 年 1 月 1 日之前的所有文件
- jquery - 数组发布为空