Baru-baru ini saya mencoba menerapkan menu tarik-turun sederhana menggunakan komponen Menu dan MenuItem MaterialUI(4.3.3).

Acara onclick pada MenuItem tidak berfungsi dengan benar. Ketika console.log(id) dipanggil, setiap komponen menggemakan elemen terakhir dari array sampel. Saya beralih ke ListItem, masalahnya hilang.


const Test = () => {
    const [anchorEl, setAnchorEl] = React.useState(null);
    const sampleArray = ["test1", "test2", "test3"];
    const open = Boolean(anchorEl);

    return (
        sampleArray.map(id => {
            let curID = id;
            return (<>
                <IconButton
                    aria-label="more"
                    aria-controls="long-menu"
                    aria-haspopup="true"
                    onClick={event => setAnchorEl(event.currentTarget)}
                >
                    <MoreHorizIcon />
                </IconButton>
                <Menu
                    elevation={0}
                    id="long-menu"
                    anchorEl={anchorEl}
                    keepMounted
                    open={open}
                    transformOrigin={{
                        vertical: 'top',
                        horizontal: 'center',
                    }}
                    onClose={() => setAnchorEl(null)}
                >
                    <MenuItem onClick={() => {
                        setAnchorEl(null);
                        console.log(curID); // should be each individual id, but here always "test3"
                    }}>Test</MenuItem>
                </Menu>
            </>);
        })
    )
}

Apakah ini perilaku yang diinginkan untuk Menu? Bagaimana cara mengatasinya?

3
Dan Lee 21 September 2019, 19:04

1 menjawab

Jawaban Terbaik

Ya, ini adalah perilaku yang diinginkan. Ini sedikit membingungkan:
Anda memiliki satu status (anchorEl), yang memutuskan apa yang menjadi jangkar untuk semua menu.
Saat Anda mengklik IconButton, Anda mengatur AnchorEl yang sama ke semua menu.
Jadi ketika Anda membuka menu, Anda sebenarnya membuka semua 3 menu di tempat yang sama!
Alasan Anda selalu mendapatkan 'test3' di konsol, adalah karena menu dengan id test3 dirender terakhir dan menu yang lain tumpang tindih.


Untuk memperbaikinya, Anda memerlukan setiap menu untuk mengelola statusnya sendiri, sehingga setiap menu akan memiliki jangkarnya sendiri:

const IsolatedMenu = props => {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const open = Boolean(anchorEl);

  return(
  <React.Fragment>
    <IconButton
    aria-label="more"
    aria-controls="long-menu"
    aria-haspopup="true"
    onClick={event => setAnchorEl(event.currentTarget)}
    >
    <PriorityHighIcon />
    </IconButton>
    <Menu
    elevation={0}
    id="long-menu"
    anchorEl={anchorEl}
    keepMounted
    open={open}
    transformOrigin={{
        vertical: 'top',
        horizontal: 'center',
    }}
    onClose={() => setAnchorEl(null)}
    >
    <MenuItem onClick={() => {
        setAnchorEl(null);
        console.log('curr id',props.id); // should be each individual id, but here always "test3"
    }}>Test</MenuItem>
    </Menu>

  </React.Fragment>
  )
}

Dan daripada komponen Tes Anda akan terlihat seperti itu:

const Test = () => {
  const sampleArray = ["test1", "test2", "test3"];

  return (
      sampleArray.map(id => {
          return (<>
            <IsolatedMenu  id={id}/>
          </>);
      })
  )
}

Edit Invisible Backdrop

5
Ido 21 September 2019, 17:06