Jak naprawić błąd "Property attributes does not exist on type EventTarget' podczas obsługi Drag&Drop?

Jak naprawić błąd "Property attributes does not exist on type EventTarget' podczas obsługi Drag&Drop?
goku21
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 91
1

Mam sobie jakąś logikę w komponencie:

Kopiuj
import { useState } from "react";
import Grid from "./Grid";

const colorsArr:Array<string> = ["red", "blue", "green", "yellow", "pink", "purple"];//, "orange"];
const gridsInRow:number = 10;
const gridsInCol:number = 10;

export type GridProps = {
    color: string;
    row:number;
    col:number;
    //key:number;
} 

function GamePlan() {

    /*const createGrids = () => {
        const arr:Array<Grid> = [];
        for(let i = 0; i < grindInCol; i++) {
            for(let j = 0; j < gridsInRow; j++) {
                arr.push(Grid());
            }
        }
        //setGridsArray(arr);
        return arr;
    }*/

    const createGrids = () => {
        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,
                    //key: i+j
                });
            }
        }
        //setGridsArray(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} />
                );
            })
            //createGrids()
        }

        </div>

    );
}

export default GamePlan;

Jak widać komponent przesyła jakieś propsy do "Dumb komponentu":

Kopiuj
return (
    <Grid key={index} color={grid.color} row={grid.row} col={grid.col} />
);

Mój "dumb komponent" wyglada tak:

Kopiuj
import { DragEventHandler, ReactEventHandler } from "react";
import { GridProps } from "./GamePlan";

function Grid(props:GridProps) {

  const row:number = props.row;
  const col:number = props.col;

  const onDragStart = (e:React.DragEvent<HTMLDivElement>) => {
      console.log("drag start",e.target.attributes.row.value);
  }

  const onDragDrop = (e:React.DragEvent<HTMLDivElement>) => {
      console.log("drag drop", e);
  }

  const onDragEnd = (e) => {
      console.log("drag end", e);
  }

  const onDragEnter = (e:React.DragEvent<HTMLDivElement>) => {
      console.log("drag enter", e);
  }


  return (
      <div className="grid" 
      style={{backgroundColor: props.color}} 
      draggable={true} 
      onDragStart={onDragStart} 
      onDrop={onDragDrop} 
      onDragEnd={onDragEnd} 
      onDragEnter={onDragEnter}
      row={row} col={col}
      >
      </div>
  );
}

export default Grid;

Być może moje zmienne row i col powinienem wrzucić do useState chociaż jeszcze się nad tym zastanawiam ponieważ w gruncie rzeczy strona się odświeży, kiedy nastąpi onDragEnd a dokładniej kiedy useState w gridsArray sie zmieni w obiekcie GamePlan. Zastanawia mnie tylko czemu typescript podkreśla tą linię:

Kopiuj
console.log("drag start",e.target.attributes.row.value);

A dokładniej warning brzmi:

Kopiuj
Property 'attributes' does not exist on type 'EventTarget'

Natomiast kiedy wejdę sobie na stronę, wsio sie wyświetla, łącznie z wartością attributes.row mimo iż rzekomo nie ma pola attributes w e.target.

Xarviel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 847
1

Jeśli chcesz robić to przez atrybuty to dodaj je jako data-*

Kopiuj
<div className="grid" 
  style={{backgroundColor: props.color}} 
  draggable={true} 
  onDragStart={onDragStart} 
  onDrop={onDragDrop} 
  onDragEnd={onDragEnd} 
  onDragEnter={onDragEnter}
  data-row={row}
  data-col={col}
/>

i odczytaj

Kopiuj
const onDragStart = (e: React.DragEvent<HTMLDivElement>) => {
    const target = e.target as HTMLDivElement; // zmieniamy typ EventTarget na dokładniejszy HTMLDivElement
    const row = target.dataset.row; // otrzymujemy wartość jako string
    // const row = target.getAttribute('data-row');

    console.log("drag start", row);

   // modyfikacja się nie uda, bo dane znikną po odświeżeniu
   // target.dataset.row = "1234";
   // target.setAttribute('data-row', '1234');
};
goku21
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 91
0

Dzięki, działa i warning zniknął ponieważ z "attributes" nie korzystam :-)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.