Home > Mobile >  draggable columns in ReactJs Antd table causes multi renders of useEffect
draggable columns in ReactJs Antd table causes multi renders of useEffect

Time:08-05

I am using antd for create a table in reactJs. I added eventListener to th tag because I want to be able to drag the columns. I do it with useRef to get all the th tags:

const [cols, setCols] = useState(columns); // -> columns is static array of object
const tableRef = useRef(null);

useEffect(() => {
    if (tableRef.current) {
      let elems = tableRef.current.ownerDocument.querySelectorAll('th');
      for (let i = 0; i < elems.length; i  ) {
        elems[i].setAttribute('draggable', true);

        elems[i].addEventListener('dragstart', (e) => {
          handleDragStart(e);
        });

        elems[i].addEventListener('dragover', (e) => {
          handleDragOver(e);
        });

        elems[i].addEventListener('drop', (e) => {
          handleOnDrop(e);
        });
      }
    }
  }, [cols]); // -> cols is the updated columns after change order

const handleDragStart = (e) => {
    const { innerText } = e.target;
    const idx = cols.findIndex((x) => x.title === innerText);
    e.dataTransfer.setData('colIdx', parseInt(idx));
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };


  const handleOnDrop = (e) => {
    const { innerText } = e.target;
    const droppedColIdx = cols.findIndex((x) => x.title === innerText);
    const draggedColIdx = parseInt(e.dataTransfer.getData('colIdx'));
    setCols(() => {
      const tempCols = [...cols];
      tempCols.splice(droppedColIdx, 0, tempCols.splice(draggedColIdx, 1)[0]);
      return tempCols;
    });
  };

My problem: The columns are draggable and I can move them. If in the useEffect dependency I add cols array, in the first drag the useEffect will call one time, in the second drag the useEffect will call 2 times, in the third drag the useEffect will call 4 times, in the fourth drag the useEffect will call 8 times and so on. That is every time the useEffect is call, it multiple the call in 2.

If I remove cols array from useEffect dependency, after the first drag everything is ok, but in the second drag my cols reset and initialized to columns.

Thank you for helping me.

CodePudding user response:

You need to remove the listeners in the return of the useEffect in the following manner:

useEffect(() => {
    const handleClick = event => {
      console.log('Button clicked');
    };

    const element = ref.current;

    element.addEventListener('click', handleClick);

    //            
  • Related