Updating a block’s edit / save without reinventing the wheel

You would do this with the format API, for example, this code from the handbook will add a <samp> tag around text:

import { registerFormatType, toggleFormat } from '@wordpress/rich-text';
import { RichTextToolbarButton } from '@wordpress/block-editor';
 
const MyCustomButton = ( props ) => {
    return <RichTextToolbarButton
        icon='editor-code'
        title="Sample output"
        onClick={ () => {
            props.onChange( toggleFormat(
                props.value,
                { type: 'my-custom-format/sample-output' }
            ) );
        } }
        isActive={ props.isActive }
    />;
};
 
registerFormatType(
    'my-custom-format/sample-output', {
        title: 'Sample output',
        tagName: 'samp',
        className: null,
        edit: MyCustomButton,
    }
);

Likewise, you can use the same tricks the image format uses to insert a single element without it wrapping text:

https://github.com/WordPress/gutenberg/blob/master/packages/format-library/src/image/index.js

Specifically, it imports insertObject:

                            insertObject( value, {
                                type: name,
                                attributes: {
                                    className: `wp-image-${ id }`,
                                    style: `width: ${ Math.min(
                                        imgWidth,
                                        150
                                    ) }px;`,
                                    url,
                                    alt,
                                },
                            } )

Where name is the name of the format that was registered. The result is an inline <img> tag.