Run code once when block is created

You can do this with a block attribute and useEffect() in your edit function:

useEffect(() => {
    // If the ID is already set, we don't need to do anything
    if (attributes.id) {
        return;
    }

    // The ID attribute isn't set, so we'll create it and set it now
    setAttributes({
        id: 123, // This is just for example purposes, you can set up your ID however you want
    });
}, []); // Empty array ensures this effect only runs once

One thing to note: This will not run your ID creation code again if you copy/paste/duplicate an existing block with an existing ID attribute.

If you’re looking for a more robust solution to generating a unique ID for a block (and are ok with the ID possibly changing), I used a similar technique (see code here) for a block of mine that combines the post ID and an instance ID to create the unique ID. If you rearrange the blocks, insert new ones, etc. it regenerates the IDs as necessary.