在单击和鼠标上的相同组件中做出反应?

时间:2020-03-10 03:25:19

标签: javascript reactjs react-hooks

我正在构建一个表。我在同一组件中添加了onMonseUp和onClick。当用户单击并拖动单元格时,它将打开对话框。但是当我在单元格中单击时,它不会打开对话框。 我想在鼠标悬停时打开对话框,当我单击它时也打开对话框

这是我的代码

export default function Table() {

    const [start, setStart] = useState(null);
    const [end, setEnd] = useState(0);
    const [selecting, setSelecting] = useState(false);
    const [isOpen, setIsOpen] = useState(false);

    let toggleModal = () => {
        setIsOpen(!isOpen);
    };

    let beginSelection = i => {
        setSelecting(true);
        setStart(i);
        updateSelection(i);
    };

    let endSelection = (i = end) => {
        setSelecting(false);
        updateSelection(i);
        toggleModal();
    };

    let updateSelection = i => {
        if(selecting) {
            setEnd(i);
        }
    };

    let cells = [];
        for(let j = 0; j < 12*4; j++) {
            cells.push(
                <Cell key={j}
                      inputColor={
                          (end <= j && j <= start || (start <= j && j <= end) ? "#adf": "")
                      }
                      onMouseDown={()=>beginSelection(j)}
                      onMouseUp={()=>endSelection(j)}
                      onMouseMove={()=> updateSelection(j)}
                      onClick={toggleModal}
                >
                    {j+1}
                </Cell>
            )
        }

    return (
        <TableCalendar>
            {cells}
            <Dialog onClose={()=> toggleModal()} show={isOpen} >
                Here's some content for the modal
            </Dialog>
        </TableCalendar>
    )
}

这是我的完整代码和演示:https://codesandbox.io/s/github/Kalipts/ReactMouseEvent

请帮助我。谢谢

3 个答案:

答案 0 :(得分:2)

摆脱onClick={toggleModal}。对于toggleModalonMouseUpendSelection来说,这是多余的,重复执行两次完全相同。

答案 1 :(得分:2)

单击时,将调用onMouseDownonMouseUp。因此,在您的情况下,toggleModalonMouseUponClick中被两次调用。这就是为什么变量将返回其值。

您可以删除onClick,只需让onMouseUp显示模态,这样您也将获得正确的选择。您也可以在onclick中直接调用setIsOpen(true)

<Cell
  key={j}
  inputColor={
    (end <= j && j <= start) || (start <= j && j <= end) ? "#adf" : ""
  }
  onMouseDown={() => beginSelection(j)}
  onMouseUp={() => endSelection(j)}
  onMouseMove={() => updateSelection(j)}
  onClick={() => setIsOpen(true)}
>
    {j + 1}
</Cell>

工作沙箱:https://codesandbox.io/s/eager-spence-58q0o

答案 2 :(得分:1)

删除toggleModal函数,然后直接执行setIsOpen()

import React, { useState } from "react";
import styled from "styled-components";
import Dialog from "./Modal";

const TableCalendar = styled.div`
  display: grid;
  grid-template-columns: repeat(12, auto);
  background-color: #2196f3;
  padding: 10px;
`;

const Cell = styled.div`
  background-color: ${props => props.inputColor || "rgba(255, 255, 255, 1)"};
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 20px;
  font-size: 30px;
  text-align: center;

  -webkit-user-select: none; /* Chrome all / Safari all */
  -moz-user-select: none; /* Firefox all */
  -ms-user-select: none; /* IE 10+ */
  user-select: none;
`;

export default function Table() {
  const [start, setStart] = useState(null);
  const [end, setEnd] = useState(0);
  const [selecting, setSelecting] = useState(false);
  const [isOpen, setIsOpen] = useState(false);

  let beginSelection = i => {
    setSelecting(true);
    setStart(i);
    updateSelection(i);
  };

  let endSelection = (i = end) => {
    setSelecting(false);
    updateSelection(i);
    setIsOpen(true)
  };

  let updateSelection = i => {
    if (selecting) {
      setEnd(i);
    }
  };

  let cells = [];
  for (let j = 0; j < 12 * 4; j++) {
    cells.push(
      <Cell
        key={j}
        inputColor={
          (end <= j && j <= start) || (start <= j && j <= end) ? "#adf" : ""
        }
        onMouseDown={() => beginSelection(j)}
        onMouseUp={() => endSelection(j)}
        onMouseMove={() => updateSelection(j)}
        onClick={() => setIsOpen(true)}
      >
        {j + 1}
      </Cell>
    );
  }

  return (
    <TableCalendar>
      {cells}
      <Dialog onClose={() => setIsOpen(false)} show={isOpen}>
        Here's some content for the modal
      </Dialog>
    </TableCalendar>
  );
}