Add multiple images to a custom block

There are other changes you need to make in your code, but as for the main one — making the mediaID and mediaURL be repeatable, the (core) gallery block did it by setting query as the attribute source and array as the attribute type.

So I would do the same and for example you can set the attribute name to images:

// Define the attribute:
attributes: {
    images: {
        type: 'array',
        source: 'query',
        selector: '.slider-item',
        default: [],

        // The following means in each .slider-item element in the saved markup,
        // the attribute value is read from the data-id or src attribute of the
        // img element in the .slider-item element. And yes of course, you can
        // change the selector to 'a', '.some-class' or something else.
        query: {
            mediaID: {
                type: 'number',
                source: 'attribute',
                attribute: 'data-id',
                selector: 'img',
            },
            mediaURL: {
                type: 'string',
                source: 'attribute',
                attribute: 'src',
                selector: 'img',
            },
        },
    },
}

/* And the attribute value would look like:
images: [
  { mediaID: 1, mediaURL: 'https://example.com/wp-content/uploads/2021/04/image.png' },
  { mediaID: 2, mediaURL: 'https://example.com/wp-content/uploads/2021/04/image2.png' },
  ...
]
*/

Then in your MediaUpload element, you would want to set the gallery and multiple properties to true (to allow multiple image selections), and in your onSelectImage() function, you can set the attribute value (which is an array) like so:

props.setAttributes( {
    images: items.map( item => {
        return {
            mediaID: parseInt( item.id, 10 ),
            mediaURL: item.url,
        };
    } ),
} );

Try My Block/Code

So it uses JSX and ESNext, but the save() output is identical to the one in the question, and you can find the code here. 🙂