Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

draggable columns in ReactJs Antd table causes multi renders of useEffect

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thank you for helping me.

>Solution :

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);

    // 👇️ remove the event listener when component unmounts
    return () => {
      element.removeEventListener('click', handleClick);
    };
  }, []);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading