4

table各行にmenuボタンが必要なリストがありますref。プロジェクトで react mui を使用していますが、それはmenuです。私は次のような参照を作成しようとしました:

const {rows} = props;
const refs = Array.from({length: rows.length}, a => React.useRef<HTMLButtonElement>(null));

そして、各関数で次のmapように関数内を使用しようとしましたbutton:

<Button
   ref={refs[index]}
   aria-controls="menu-list-grow"
   aria-haspopup="true"
   onClick={() => handleToggle(row.id)}
>Velg
</Button>
  <Popper open={!!checkIfOpen(row.id)} anchorEl={refs[index].current} keepMounted transition disablePortal>
    {({TransitionProps, placement}) => (
       <Grow
        {...TransitionProps}
        style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'}}>
       <Paper id="menu-list-grow">
         <ClickAwayListener onClickAway={(e) => handleClose(e, refs[index].current)}>
          <MenuList>                                                        
            <MenuItem
             onClick={(e) => handleClose(e, refs[index].current)}>Profile</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs[index].current)}>My account</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs[index].current)}>Logout</MenuItem>
        </MenuList>
      </ClickAwayListener>
    </Paper>
  </Grow>
 )}
</Popper>

しかし、その後、エラーが発生します:

React Hook "React.useRef" は、コールバック内で呼び出すことはできません。React Hooks は、React 関数コンポーネントまたはカスタム React Hook 関数で呼び出す必要があります react-hooks/rules-of-hooks

map 関数内で参照を使用できるように、これを動的に行うにはどうすればよいですか。回答の提案を試してみましたが、うまくいきませんでした。これが例のコードサンドボックスです。

4

2 に答える 2

7

useRefReact.createRef とまったく同じではありません。それを呼び出す方が良いですuseInstanceField:)

したがって、コードは少し異なる可能性があります。

最初のステップ:useRef参照の配列を保存するために使用します。

const {rows} = props;
const refs = useRef(Array.from({length: rows.length}, a => React.createRef()));

次に、マップ関数で、各参照を refs 配列のインデックスに保存します。

<Button
   ref={refs.current[index]}
   aria-controls="menu-list-grow"
   aria-haspopup="true"
   onClick={() => handleToggle(row.id)}
>Velg
</Button>
  <Popper open={!!checkIfOpen(row.id)} anchorEl={refs.current[index].current} keepMounted transition disablePortal>
    {({TransitionProps, placement}) => (
       <Grow
        {...TransitionProps}
        style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'}}>
       <Paper id="menu-list-grow">
         <ClickAwayListener onClickAway={(e) => handleClose(e, refs.current[index].current)}>
          <MenuList>                                                        
            <MenuItem
             onClick={(e) => handleClose(e, refs.current[index].current)}>Profile</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs.current[index].current)}>My account</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs.current[index].current)}>Logout</MenuItem>
        </MenuList>
      </ClickAwayListener>
    </Paper>
  </Grow>
 )}
</Popper>

長さが変更された場合は、それを処理してuseEffect参照の長さを変更する必要があります

別の方法を使用することもできます。

1) ref の配列を作成しますが、React.createRef は使用しません。

const {rows} = props;
const refs = useRef(new Array(rows.length));

マップではref={el => refs.current[index] = el}、参照を保存するために使用します

<Button
   ref={el => refs.current[index] = el}
   aria-controls="menu-list-grow"
   aria-haspopup="true"
   onClick={() => handleToggle(row.id)}
>Velg
</Button>
  <Popper open={!!checkIfOpen(row.id)} anchorEl={refs.current[index].current} keepMounted transition disablePortal>
    {({TransitionProps, placement}) => (
       <Grow
        {...TransitionProps}
        style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'}}>
       <Paper id="menu-list-grow">
         <ClickAwayListener onClickAway={(e) => handleClose(e, refs.current[index])}>
          <MenuList>                                                        
            <MenuItem
             onClick={(e) => handleClose(e, refs.current[index])}>Profile</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs.current[index])}>My account</MenuItem>
           <MenuItem onClick={(e) => handleClose(e, refs.current[index])}>Logout</MenuItem>
        </MenuList>
      </ClickAwayListener>
    </Paper>
  </Grow>
 )}
</Popper>
于 2019-09-12T07:40:56.813 に答える