Zalezy co macie na mysli mowiac o efektach ubocznych :-) Na moj chlopski rozum funkcja generuje po prostu jakas kolorowa siatke i nic wiecej, zdziwilo mnie tylko to, ze funkcja uruchamia sie dwa razy i zaczałem szukac wtf:> Do głowy by mi nie przyszlo ze js moze to generowac 2 razy po prostu w celach szukania błędów.
Swoją drogą jak widzicie funkcja nie genereuje grida a gridpropsy z prostego powodu, grid jest jakims tam divem (czy img pewnie w przyszlosci:
import { useState } from "react";
import Grid from "./Grid";
import { DragGridCalculations } from "./DragGridCalculations";
export const gridsInRow:number = 6;
export const gridsInCol:number = 3;
const colorsArr:Array<string> = ["red", "blue", "green", "yellow", "pink", "purple"];//, "orange"];
let indexStartDrag:number;
const dragCalc:DragGridCalculations = new DragGridCalculations();
export type GridProps = {
color: string;
row:number;
col:number;
onDragStart: (e:React.DragEvent<HTMLDivElement>) => void;
onDragDrop: (e:React.DragEvent<HTMLDivElement>) => void;
//key:number;
//grid:GridProps;
}
function GamePlan() {
const onDragStart = (e:React.DragEvent<HTMLDivElement>) => {
dragCalc.setGridStart(e);
const target = e.target as HTMLDivElement;
console.log(e);
const row:number = Number(target.dataset.row); const col = Number(target.dataset.col);
console.log(row + " a w tablicy to chyba : " + (row*gridsInCol + col));
console.log("drag start " + row); //e.target.attributes.row.value);
indexStartDrag = row*gridsInCol + col;
console.log(indexStartDrag);
e.stopPropagation();
}
const onDragDrop = (e:React.DragEvent<HTMLDivElement>) => {
const target = e.target as HTMLDivElement;
const dropRow:number = Number(target.dataset.row);
const dropCol:number = Number(target.dataset.col);
const indexDrop:number = dropRow*gridsInCol + Number(target.dataset.col);
console.log("index drop: " + indexDrop + " a drop row: " + dropRow + " a drop col: " + dropCol);
const tempStartDragGridObj:GridProps = gridsArray[indexStartDrag];
const tempDropGridObj:GridProps = gridsArray[indexDrop];
if(dragCalc.isAbleToMove(e))
{
tempDropGridObj.row = tempStartDragGridObj.row;
tempDropGridObj.col = tempStartDragGridObj.col;
tempStartDragGridObj.row = dropRow;
tempStartDragGridObj.col = dropCol;
const tempArr = gridsArray;
tempArr[indexStartDrag] = tempDropGridObj;
tempArr[indexDrop] = tempStartDragGridObj;
//setGridsArray((prev) => tempArr);
setGridsArray(() => [...tempArr]);
dragCalc.checkGridsFit(gridsArray, e);
}
}
const createGrids = ():Array<GridProps> => {
const arr:Array<GridProps> = [];
for(let i = 0; i < gridsInRow; i++) {
for(let j = 0; j < gridsInCol; j++) {
arr.push({
color:colorsArr[Math.floor(Math.random() * colorsArr.length)],
row: i,
col: j,
onDragStart: onDragStart,
onDragDrop: onDragDrop,
//key: i*9 + j,
});
}
}
console.log(arr.length, arr);
return arr;
}
const [gridsArray, setGridsArray] = useState<GridProps[]>(createGrids);
return (
<div style={{display: "flex", flexWrap: "wrap", width: 560}}>
{
gridsArray.map((grid, index) => {
return (
<Grid key={index} color={grid.color} row={grid.row} col={grid.col} onDragStart={onDragStart} onDragDrop={onDragDrop} />
);
})
}
</div>
);
}
export default GamePlan;
import { DragEventHandler, ReactEventHandler } from "react";
import { GridProps } from "./GamePlan";
function Grid(props:GridProps) {
const row:number = props.row;
const col:number = props.col;
const color:string = props.color;
const onDragEnd = (e) => {
console.log("drag end", e);
}
const onDragOver = (e) => {
console.log("drag over " + e.clientX, e);
e.preventDefault();
}
return (
<div className="grid"
style={{backgroundColor: props.color}}
draggable={true}
onDragStart={props.onDragStart}
onDrop={props.onDragDrop}
onDragEnd={onDragEnd}
//onDragEnter={onDragEnter}
//onDragOver={(e)=> e.preventDefault()}
onDragOver={onDragOver}
data-row={row} data-col={col}
>
</div>
);
}
export default Grid;
I pewnie sam Grid w przyszlosci tez bedzie musiał używać jakiegos usestate np w zwiazku z animacja czy to wybuchu czy spadania itd.
Tyle ze to rodzi pewne komplikacje ponieważ normalnie napisałbym Grida jako klase i po prostu tworzył instancję danej klasy. Cos w stylu
for....
let grid = new Grid(color, row, col, blebleble);
arr.push(grid);
Wtedy po kliknieciu w grida dostawalbym w e.target konkretnego grida gedzie bym sobie mial swobodny dostep do wszelkich pól (czy tam zmiennych) jakie bym sobie ustawił w instancji klasy.
Tutaj jednak musze bawic sie w jakies propsy ktore z kolei utrudniaja mi dostep do danych. Musze np. robic cos w stylu:
const target = e.target as HTMLDivElement;
const dropRow:number = Number(target.dataset.row);
const dropCol:number = Number(target.dataset.col);
const indexDrop:number = dropRow*gridsInCol + Number(target.dataset.col);
i te dane z kolei przesyłac tez w jakis dziwny posob:
<div style={{display: "flex", flexWrap: "wrap", width: 560}}>
{
gridsArray.map((grid, index) => {
return (
<Grid key={index} color={grid.color} row={grid.row} col={grid.col} onDragStart={onDragStart} onDragDrop={onDragDrop} />
);
})
}
</div>
Co rozwala mi łeb ponieważ cały czas musze mieć z tyłu głowy ze 1 taki prosty element jak Grid czyli zwykły kolorowy kwadrat w który mozna klikać ma jakieś tak naprawdę 2 warstwy, warstwę props ze wszystkimi danymi i warstwę przeznaczoną do wyswietlenia w formie komponentu. Nie wydaje to się wam dziwactwem?