在下拉模式中使用模态反应 CTA



我正在使用MaterialUI的ButtonGroup作为下拉菜单,并且在尝试创建一系列CTA时遇到了模式问题,我可以轻松地在其中交换这些CTA;其中所有组件都是可重用的,下拉列表中的选择是动态的,即

const CTAs = [
<Foo {...foo} />, // these look like <MenuItem>{blah}</MenuItem>
<Bar {...bar} />,
<Baz {...baz} />,
];
return (
<DropDown>
{CTAs}
</DropDown>
);
// DropDown looks something like this
const [open, setOpen] = React.useState<boolean>(false);
const anchorRef = React.useRef<HTMLDivElement>(null);
return (
<Grid container direction="column" alignItems="center">
<Grid item xs={12}>
<ButtonGroup variant="contained" ref={anchorRef}>
<Button
variant="contained"
onClick={toggleOpen}
>
{label}
</Button>
</ButtonGroup>
<ListWrapper
anchorEl={anchorRef.current}
open={open}
setOpen={setOpen}
> {/* Popper > Grow > Paper > ClickAwayListener > MenuList > children */}
{children}
</ListWrapper>
</Grid>
</Grid>
);

但是,当其中一些 CTA 需要模态确认时,我遇到了问题,因为模态在下拉列表中中断; 下拉列表捕获文本条目,关闭下拉列表会破坏模态。

我该怎么做?


我尝试过的,

我通过添加一个返回两个节点而不仅仅是一个节点的函数来解决此问题;

interface CTAState {
open: boolean;
// and other stuff that used to be inside the CTAs
}
const GetFoo = (props): [React.ReactNode, React.ReactNode] => {
const [state, setState] = React.useState<CTAState>({ open: false });
const setOpen = (val: boolean): void => setState((prevState) => ({
...prevState,
open: val,
}));
const onSend = (): void => {
// do cool stuff which used to be in <Foo /> click
setOpen(false);
};
return [
(<Foo {...props} onClick={() => setOpen(true)} />),
(<Dialog open={state.open} onSend={onSend} />),
];
};
// .. 
const CTAs = [GetFoo(foo), GetBar(bar), GetBaz(baz)];
return (
<DropDown>
{CTAs.map(([button]) => button)}
</DropDown>
{CTAs.map(([, dialog]) => dialog)}
);

这似乎是一种反模式,因为我不得不使用不是带有反应钩子的组件来处理状态的东西,复杂性不断增加,并且很难跟踪 CTA 本身正在

发生的事情有什么方法可以做到这一点?

如果我理解正确,模态确认会关闭下拉列表,对吧?如果是这样,请尝试以下操作:

// ...
<ListWrapper
anchorEl={anchorRef.current}
open={open}
setOpen={(event) => {
event.preventDefault()
setOpen(event)
}}
> {/* Popper > Grow > Paper > ClickAwayListener > MenuList > children */}
{children}
</ListWrapper>
// ...

最新更新