Skip to content

useId generates duplicate identifiers in some cases when calling render from @preact/compat multiple times #4223

@Kauhsa

Description

@Kauhsa

useId generates duplicate identifiers in some cases when calling render from @preact/compat multiple times.

To Reproduce

Run the following in browser of your choice (I used Chrome 119.0.6045.159):

<script type="module">
    import { createElement, useId, render } from 'https://esm.sh/@preact/compat@17.1.2';
    
    // You can check React behaviour with replacing the import above with this:
    // import { createElement, useId } from 'https://esm.sh/stable/react@18.2.0/es2022/react.mjs'
    // import { render } from 'https://esm.sh/stable/react-dom@18.2.0/es2022/react-dom.mjs'
    
    const e = createElement;

    const Id = () => {
        const id = useId();
        return e('div', {}, `My id is ${id}`);
    }

    const App = (props) => {
        return e('div', {}, [
            e(Id, {}),
            props.secondId ? e(Id, {}) : null,
        ]);
    }

    render(e(App, { secondId: false }), document.body);
    render(e(App, { secondId: true }), document.body);
</script>

Preact renders the following:

My id is P0-0
My id is P0-0

If line render(e(App, { secondId: false }), document.body); is removed, identifiers are unique:

My id is P0-0
My id is P0-1

Expected behavior

Non-unique identifiers cause issues when using return values as HTML id parameters, for example. React seems to handle this properly:

My id is :r0:
My id is :r1:

I am unsure if multiple calls to render function is intended usage of API in preact, but even if not, @preact/compat probably should replicate the behaviour of React here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions