0

I'm working on a Gutenberg block that will be a dropdown menu of all posts on the site. I used @wordpress/create-block (version 4.4.0) for the scaffolding. When I try to use the useSelect function, it get "This block has encountered an error and cannot be previewed." in addition to an error:

enter image description here

I'm trying to use code that was previously successful, although that code did not use the @wordpress/create-block scaffolding (I built everything from scratch and the @wordpress/scripts npm).

Here's my code:

 import {useSelect} from "@wordpress/data"

 export default function Edit() {
    const allCPTposts = useSelect(select => {

        return select("core").getEntityRecords("postType", "post", {per_page: -1})
    })

    if(allCPTposts == undefined){
        return <p>Loading Posts...</p>
    }

    return (
        <p { ...useBlockProps() }>
            { __( 'Dropdown Menu – hello from the editor!', 'dropdown' ) }
        </p>
    );
}

I'm not able to even work on the JSX for the actual dropdown menu because of this error.

Any ideas? Thank you in advance!

4
  • The error reads "Rendered more hooks than during the previous render." - so I'd assume the useBlockProps() is the culprit here. If you move that above the conditional return, does it work again?
    – kero
    Commented Nov 17, 2022 at 14:40
  • @kero That absolutely fixed it! Thank you very much! Commented Nov 17, 2022 at 15:04
  • Unrelated to your error, you've tried to use per_page: -1 which is not possible, and if it were possible would be dangerous. The REST API caps requests at 100 posts for performance and scaling reasons. Arguably you should also be doing this in server side queries but there is no cap there, so while you can try to use -1, you will never get all posts unless there are less than 100. The API returns 10 per page by default
    – Tom J Nowell
    Commented Nov 17, 2022 at 15:07
  • @kero please post your answer as an answer, not a comment
    – Tom J Nowell
    Commented Nov 17, 2022 at 15:08

1 Answer 1

1

If you check the URL given with the error message, you will see the full text as:

Rendered more hooks than during the previous render.

Inspecting the code, I see two uses of hooks:

export default function Edit() {
    const allCPTposts = useSelect(select => {
//                      ^ first hook use 
        return select("core").getEntityRecords("postType", "post", {per_page: -1})
    })

    if(allCPTposts == undefined){
        return <p>Loading Posts...</p>
    }

    return (
        <p { ...useBlockProps() }>
{/*             ^ second hook use */}
            { __( 'Dropdown Menu – hello from the editor!', 'dropdown' ) }
        </p>
    );
}

So it seems sometimes just useSelect() and sometimes both useSelect() and useBlockProps() are called.

Seeing that there is an early return before the second hook use, this is most likely the issue here. Just move the useBlockProps() call above the early return and the component will always call the same amount of hooks for each render.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.