英文:
React-drid-layout - onClick event
问题
我需要在<GridLayout>组件上使用onClick处理程序,这是来自react-grid-layout的。思路是,我有一个父<GridLayout>,但我也可以在其中创建新的子布局。但是当我点击父<GridLayout>(而不是它的子项)时,我应该将活动布局设置为1。
我尝试了这段代码:
import "./styles.css";
import GridLayout from "react-grid-layout";
import { useState, useRef } from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
export default function CustomLayout({ layout, onDragStart, onDragStop }) {
  const [isDraggable, setIsDraggable] = useState(true);
  const [active, setActive] = useState(2);
  const gridLayoutRef = useRef(null);
  console.log("state", active);
  const handleClick = (event) => {
    const x = event.nativeEvent.offsetX;
    const y = event.nativeEvent.offsetY;
    const layout = gridLayoutRef.current.state.layout;
    for (let i = 0; i < layout.length; i++) {
      const item = layout[i];
      if (
        x >= item.x &&
        x <= item.x + item.w &&
        y >= item.y &&
        y <= item.y + item.h
      ) {
        setActive(2);
        return;
      }
    }
    setActive(1);
  };
  return (
    <GridLayout
      className="layout"
      onDragStart={onDragStart}
      onDragStop={onDragStop}
      layout={layout}
      cols={12}
      rowHeight={80}
      width={1200}
      isDraggable={isDraggable}
      ref={gridLayoutRef}
    >
      {layout.map((item) => {
        if (item.children) {
          return (
            <div
              key={item.i}
              style={{ background: "pink", border: "1px solid black" }}
            >
              <CustomLayout
                layout={item.children}
                onDragStart={() => {
                  setIsDraggable(false);
                }}
                onDragStop={() => {
                  setIsDraggable(true);
                }}
              />
            </div>
          );
        } else {
          return (
            <div key={item.i} style={{ background: "purple", color: "#fff" }}>
              {item.i}
            </div>
          );
        }
      })}
    </GridLayout>
  );
}
思路很简单 - 我获取了点击的坐标并检查是否存在子元素。但问题在于,onClick事件不起作用。是否有解决此问题的方法?我知道可以创建一个按钮来将状态设置为我想要的状态,但我需要类似于clickOut事件的东西。
如果有人想更仔细地查看,我会留下我的CodeSandbox示例链接:https://codesandbox.io/s/amazing-chatterjee-wzsq62?file=/src/gridLayout.js:0-1882
英文:
I need to somehow use onClick handler on <GridLayout> from react-grid-layout. The idea - I have a parent <GridLayout>, but I can also create new child layouts inside of it. But when I click on parent <Gridlayout> (but not on it's item) i should set active layout to 1.
I tried this code:
import "./styles.css";
import GridLayout from "react-grid-layout";
import { useState, useRef } from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
export default function CustomLayout({ layout, onDragStart, onDragStop }) {
const [isDraggable, setIsDraggable] = useState(true);
const [active, setActive] = useState(2);
const gridLayoutRef = useRef(null);
console.log("state", active);
const handleClick = (event) => {
const x = event.nativeEvent.offsetX;
const y = event.nativeEvent.offsetY;
const layout = gridLayoutRef.current.state.layout;
for (let i = 0; i < layout.length; i++) {
const item = layout[i];
if (
x >= item.x &&
x <= item.x + item.w &&
y >= item.y &&
y <= item.y + item.h
) {
setActive(2);
return;
}
}
setActive(1);
};
return (
<GridLayout
className="layout"
onDragStart={onDragStart}
onDragStop={onDragStop}
layout={layout}
cols={12}
rowHeight={80}
width={1200}
isDraggable={isDraggable}
ref={gridLayoutRef}
>
{layout.map((item) => {
if (item.children) {
return (
<div
key={item.i}
style={{ background: "pink", border: "1px solid black" }}
>
<CustomLayout
layout={item.children}
onDragStart={() => {
setIsDraggable(false);
}}
onDragStop={() => {
setIsDraggable(true);
}}
/>
</div>
);
} else {
return (
<div key={item.i} style={{ background: "purple", color: "#fff" }}>
{item.i}
</div>
);
}
})}
</GridLayout>
);
}
The idea is simple - i get the coordinates of my click and check if there is a child element. But here comes the issue - onClick event doesn't work. is there any way to solve this issue? I know can create a button to set my state to what i want it to be, but I need something like a clickOut event. <br/>
I'll leave a link to my CodeSandbox example in case someone wants to have a closer look: https://codesandbox.io/s/amazing-chatterjee-wzsq62?file=/src/gridLayout.js:0-1882
答案1
得分: 2
根据我从你发布的代码中理解的情况,似乎在父级 GridLayout 上未触发 onClick 事件,看起来它不是一个可点击的元素。
如果你将 GridLayout 包裹在一个可点击的容器元素中,比如一个 div,并将 onClick 事件附加到该容器,类似下面这样:
import "./styles.css";
import GridLayout from "react-grid-layout";
import { useState, useRef } from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
export default function CustomLayout({ layout, onDragStart, onDragStop }) {
  const [isDraggable, setIsDraggable] = useState(true);
  const [active, setActive] = useState(2);
  const gridLayoutRef = useRef(null);
  useEffect(() => {
    console.log("state", active);
  }, [active])
  const handleClick = (event) => {
    const x = event.nativeEvent.offsetX;
    const y = event.nativeEvent.offsetY;
    const layout = gridLayoutRef.current.state.layout;
    for (let i = 0; i < layout.length; i++) {
      const item = layout[i];
      if (
        x >= item.x &&
        x <= item.x + item.w &&
        y >= item.y &&
        y <= item.y + item.h
      ) {
        setActive(2);
        return;
      }
    }
    setActive(1);
  };
  return (
    <div onClick={handleClick}>
      <GridLayout
        className="layout"
        onDragStart={onDragStart}
        onDragStop={onDragStop}
        layout={layout}
        cols={12}
        rowHeight={80}
        width={1200}
        isDraggable={isDraggable}
        ref={gridLayoutRef}
      >
        {layout.map((item) => {
          if (item.children) {
            return (
              <div
                key={item.i}
                style={{ background: "pink", border: "1px solid black" }}
              >
                <CustomLayout
                  layout={item.children}
                  onDragStart={() => {
                    setIsDraggable(false);
                  }}
                  onDragStop={() => {
                    setIsDraggable(true);
                  }}
                />
              </div>
            );
          } else {
            return (
              <div key={item.i} style={{ background: "purple", color: "#fff" }}>
                {item.i}
              </div>
            );
          }
        })}
      </GridLayout>
    </div>
  );
}
希望这能有所帮助。如果需要进一步的帮助,请随时告诉我。
英文:
Based on my understanding from the code you posted, onClick event is not being triggered on the parent GridLayout and it looks like it's not a clickable element.
What if you wrap the GridLayout with a clickable container element, such as a div, and attach the onClick event to that container, something like below:
import "./styles.css";
import GridLayout from "react-grid-layout";
import { useState, useRef } from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
export default function CustomLayout({ layout, onDragStart, onDragStop }) {
const [isDraggable, setIsDraggable] = useState(true);
const [active, setActive] = useState(2);
const gridLayoutRef = useRef(null);
useEffect(()=>{
console.log("state", active);
},[active])
const handleClick = (event) => {
const x = event.nativeEvent.offsetX;
const y = event.nativeEvent.offsetY;
const layout = gridLayoutRef.current.state.layout;
for (let i = 0; i < layout.length; i++) {
const item = layout[i];
if (
x >= item.x &&
x <= item.x + item.w &&
y >= item.y &&
y <= item.y + item.h
) {
setActive(2);
return;
}
}
setActive(1);
};
return (
<div onClick={handleClick}>
<GridLayout
className="layout"
onDragStart={onDragStart}
onDragStop={onDragStop}
layout={layout}
cols={12}
rowHeight={80}
width={1200}
isDraggable={isDraggable}
ref={gridLayoutRef}
>
{layout.map((item) => {
if (item.children) {
return (
<div
key={item.i}
style={{ background: "pink", border: "1px solid black" }}
>
<CustomLayout
layout={item.children}
onDragStart={() => {
setIsDraggable(false);
}}
onDragStop={() => {
setIsDraggable(true);
}}
/>
</div>
);
} else {
return (
<div key={item.i} style={{ background: "purple", color: "#fff" }}>
{item.i}
</div>
);
}
})}
</GridLayout>
</div>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论