Как создать портал react в раскрывающемся списке ant-design

#javascript #reactjs #antd #react-portal

Вопрос:

Я использую раскрывающийся компонент ant-design с действием щелчка правой кнопкой мыши внутри.

Я хочу иметь возможность увеличивать сразу на 5 или 10. Но всякий раз, когда на это нажимается, он будет игнорировать один из прослушивателей onClick для Menu.Item .

 const App = () => {
  const [counter, setCounter] = useState(1);

  const menu = (
    <Menu>
      <Menu.Item key="five" onClick={() => setCounter(counter   5)}>
        by 5
      </Menu.Item>
      <Menu.Item key="ten" onClick={() => setCounter(counter   10)}>
        by 10
      </Menu.Item>
    </Menu>
  );

  return (
    <div>
      <p>Counter: {counter}</p>
      <div onClick={() => setCounter(counter   1)} style={STYLING}>
        <p>Click here to increment</p>
        <Dropdown overlay={menu} trigger={["contextMenu"]}>
          <span>
            Right click here for custom increment
          </span>
        </Dropdown>
      </div>
    </div>
  );
};
 

Пример Codesandbox: https://codesandbox.io/s/contextmenu-with-dropdown-antd-n4c5i?file=/index.js

Я пытался поиграть с ReactDOM.createPortal, но я просто не могу понять, как правильно использовать его в подобном сценарии.

Я знаю, что мне, вероятно, не следует переходить к решению createPortal, но причина, по которой мне это нужно, не в этом простом примере, но я хочу, чтобы эта функциональность была в заголовке столбца таблицы ant-design, а также поддерживала сортировку.

Ответ №1:

Я решил, что мне не нужно использовать порталы. Вместо этого я могу использовать stopPropagation, чтобы запретить любому родительскому узлу получать событие onClick.

В Menu.Item событии onClick стандартное событие javascript доступно в domEvent поле.

Таким образом, мы можем создать функцию, подобную этой:

 const menuOnClick = (amount) => (e) => {
  e.domEvent.stopPropagation();
  setCounter(counter   amount);
};
 

и обновите наши Menu.Item обратные вызовы onClick до этого

 <Menu.Item key="five" onClick={menuOnClick(5)}>
 

Пример песочницы: https://codesandbox.io/s/contextmenu-with-dropdown-antd-solution-8029o?file=/index.js