在DropDown模式中使用模式的React CTA。

问题描述 投票:0回答:1

我正在使用MaterialUI的ButtonGroup作为下拉菜单,并且有一个模式问题,试图创建一系列的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)}
);

这似乎是一个反模式,因为我不得不使用一些不是Component的东西,用一个react钩子来处理状态,复杂性不断增加,而且变得很难跟踪CTA本身发生了什么。

有什么方法可以做到这一点?

javascript reactjs typescript material-ui anti-patterns
1个回答
0
投票

如果我的理解是正确的,模式确认会关闭下拉菜单,对吗?如果是这样,请尝试以下方法。

// ...
<ListWrapper
    anchorEl={anchorRef.current}
    open={open}
    setOpen={(event) => {
        event.preventDefault()
        setOpen(event)
    }}

> {/* Popper > Grow > Paper > ClickAwayListener > MenuList > children */}
    {children}
</ListWrapper>
// ...
© www.soinside.com 2019 - 2024. All rights reserved.