英文:
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>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论