Can we write custom DOM manipulation inside edit.js file while developing custom Gutenberg block?

I have doubts while creating a custom Gutenberg block are we allowed to directly manipulate DOM?

Yes but not in the way you’ve done, that’s not how React code works. When a react component is no longer shown it ceases to exist, and the associated DOM node vanishes, along with all its event handlers. This is both expected and desirable.

This isn’t a WordPress/Gutenberg question, it’s more generic than that.

For this reason, using document.querySelector on DOM nodes created by React is very very risky and fragile. E.g. blocks that aren’t on the screen, or hidden in containers won’t be found by the query selector in the code in the question, nor will that list update as headings update/change/move. Headings that are offscreen won’t even display in the DOM due to virtual list optimisations.

If you’re asking so that you can save time and effort learning React then this will not save you time, and it will not be faster/quicker.

Instead, take a look at the terms and conditions block that already exists, and also take a look at block styles and block variants. Writing a new block from scratch is probably unnecessary

I want to know how much portion of this can be moved to edit.js or save.js files?

To save.js none of it, that would mean the TOC is set in stone and unchangeable in the database until the next time it’s saved. This might break your frontend code. Remember, the save component is there to generate a static string of HTML to save in the database, nothing more.

The edit.js, not much, the approach taken to get a list of headings won’t work well in the editor, it would be easier and more reliable to query the WordPress APIs to get this information than to inspect the DOM for it.

Hint: With a null save funciton/component you can render a blocks output in PHP, and even override the output of an existing core block in PHP to print whatever you want. You can even change your edit component to server side rendering to grab the PHP rendered output.

tech