Use core block functionality in a custom block gutenberg

There may be several other issues interacting here, but the big one is here:

        function onSelectImages(media) {
            const imagesUrl = values({...media}).map((item, i) => {
                return ({id: item.id, url:item.url});
            })
            setAttributes({ selectedImages: (values({...imagesUrl})) });
        }

When images are picked, you grab the images and set them as the selected images. This is not the same as adding them, You need to fetch the existing selected Images and append the two.

The assumption is that media contains all the selected images, and that you’ve added images. This is incorrect.

Instead, you’ve chosen images, and it’s the images you chose that are in media, and you’re setting it. Unless you re-chose the images from before, they aren’t in there.

What you’re currently doing is the equivalent of something like this in PHP:

$images = [];

function on_new_images( $new_images ) {
     $new_urls_ids = foreach new images get URLs and IDs...
     $images = $new_urls_ids;
}

When really what you want is more like this:

$images = [];

function on_new_images( $new_images ) {
     $new_urls = foreach new images get URLs...
     $images = array_merge( $images, $new_urls );
}

But the JS equivalent