How to create a custom Gutenberg block with a dynamic render callback in WordPress?

I’m trying to create a custom Gutenberg block in WordPress that renders its content dynamically on the server side using PHP.

I’ve registered the block using register_block_type, and added a render_callback function, but nothing appears in the editor or frontend.

function myplugin_register_block() {
    register_block_type( __DIR__ . '/my-block', array(
        'render_callback' => 'myplugin_render_my_block',
    ));
}
add_action( 'init', 'myplugin_register_block' );

function myplugin_render_my_block( $attributes ) {
    return '<div class="dynamic-block">Hello, this is dynamic content!</div>';
}

import { registerBlockType } from '@wordpress/blocks';

registerBlockType('myplugin/dynamic-block', {
    edit: () => {
        return <p>Hello from the editor!</p>;
    },
    save: () => {
        return null; // Dynamic rendering
    },
});

What I’ve tried:
Checked if the function name is correct

Flushed permalinks

Ensured that the PHP file is loaded properly

Confirmed that block assets (JS/CSS) load correctly

What I expect:
When I insert the block in the editor, I want to see:

A preview (even just a placeholder),

And when I view the post on the frontend, the HTML returned from render_callback().