javascript - 如何使用包装器控制按钮的切换
问题描述
我正在构建一个切换按钮,规范告诉我一组切换按钮应该具有只允许单击(参见示例)和多次单击(参见示例)的行为。
多次单击很好,因为没有太多逻辑要实现,但是单击对我来说很难。使用单击的主要思想是,如果我切换一个按钮并尝试切换另一个按钮,前一个应该失去他的状态,pressed
而被点击的那个应该有它。当pressed
为 true 时,ToggleButton 具有不同的 CSS。
这是我的切换按钮组件:
const ToggleButton = props => {
const { onClick, value, ...other } = props;
const [pressed, setPressed] = useState(true);
const renderPressedButton = () => {
setPressed(!pressed);
if (onClick) {
onClick();
}
};
return (
<StyledToggleButton
className={!pressed ? 'pressed' : null}
pressed={pressed}
data-value={value}
{...other}
onClick={renderPressedButton}
/>
);
};
这是我的包装器(atm 我只得到我点击的类):
const onClickHandler = e => {
const index = e.target.closest('.pressed');
// console.log(index);
// console.log('classe: ', e.target.className);
if (index) {
console.log('its pressed!');
}
};
const ToggleButtonGroup = props => {
const { ...other } = props;
return <StyledToggleButtonGroup onClick={onClickHandler} {...other} />;
};
我认为我应该使用 Context API 或者将我的renderPressedButton
逻辑移动到我的包装器中。有人有想法吗?
这就是我计划使用该组件的方式:
<ToggleButtonGroup singleClick>
<ToggleButton>One</ToggleButton>
<ToggleButton>Two</ToggleButton>
</ToggleButtonGroup>
解决方案
将状态提升至ToggleButtonGroup
。在那里维护一个切换索引的列表,并提供一个布尔值作为道具来ToggleButton
保持它完全无状态。通过这种方式,您将能够根据任何点击ToggleButton
单独控制每个。ToggleButtonGroup
function ToggleButtonGroup({ singleClick, children }) {
const [checked, setChecked] = React.useState([]);
const handleClick = event => {
// event.target should have your clicked checbox reference
const index = event.target.dataset.index;
if (singleClick) {
setChecked([index]);
} else {
if (checked.includes(index)) {
setChecked(checked.filter(eachIndex => eachIndex !== index));
} else {
setChecked([...checked, index]);
}
}
};
return (
<div onClick={handleClick}>
{React.Children.map(children, (child, index) => {
return React.cloneElement(child, {
dataIndex: index,
pressed: checked.includes(index)
});
})}
</div>
);
}
function ToggleButton({ dataIndex, pressed, ...rest }) {
return <div data-index={dataIndex} className={!pressed ? 'pressed' : null} {...rest} />;
}
推荐阅读
- settings - 如何更改标题栏和页面中的铬名称
- firebase - Firebase 示例函数“generateThumbnail”不会部署
- flutter - ListView 中的 Dismissible 从 PageView 拾取滑动
- bash - 如果命令是子进程程序的结果,bash如何搜索程序
- html - 居中
- 不考虑项目符号的元素
- python - 使用 numpy 执行 .sum() 操作时跳过字符串
- jquery - 如何使用 jquery 更改未嵌套在子标签中的文本?
- python - 查找最低测试分数和两个高分的平均值
- python - urllib.request:POST 数据应该是字节、字节的可迭代或文件对象
- c# - 将对象添加到列表时如何修复覆盖