0

In my block's edit() function i'm getting the index of each inner block:

// a block used in innerblocks
edit( { attributes, setAttributes, clientId } ) {

    let blockIndex = wp.data.select( 'core/editor' ).getBlockIndex( clientId );
    
    ...

This works fine. However i tried the same in save() but I get index -1 for each block. How can I make getBlockIndex() work in save()?

I need to add index number to class names of inner blocks in HTML.

1
  • 1
    this doesn't make sense, and is an antipattern. A block should always return the same output given the same attributes, if you succeed in what you are doing you will immediately face block validation problems that stop you in your tracks. Save components should only use block attributes, they shouldn't select things, use state, have interactive components, etc
    – Tom J Nowell
    Jan 8, 2022 at 17:00

1 Answer 1

1

You cannot use wp.select in your save component, a save component can only use the block attributes. If you generate markup from using data from other sources then it will fail block validation.

If you want data such as the index of the block, you need to store it in the attributes in the edit component, or render the block in PHP.

The same goes for other "effects", you should not do these things in a save component:

  • use state
  • make HTTP requests
  • retrieve data that didn't come from block attributes
  • interactive components
  • query the data store
  • react hooks e.g useEffect or useCallback
  • prompt the user for data
  • extract data from DOM nodes or global variables

The job of a save component is to take the blocks attributes and turn them into static HTML that gets saved in the database. Any interactivity or effects that do work need to go in the edit component or elsewhere, and their results stored in attributes.

6
  • 1
    Thanks. I added the blockindex to an attribute then used that in save().
    – CyberJ
    Jan 9, 2022 at 1:09
  • But we can use <RichText /> to prompt the user for data, right?
    – m4n0
    Oct 5, 2022 at 20:32
  • 1
    In an edit component yes, but in a save component? Never. That doesn't make sense, save components are never rendered and shown to the user, there is no way to prompt the user for data in a save component. Interactive components must go in the edit component. The only purpose of a save component is to generate HTML static strings that are going to be saved in the database
    – Tom J Nowell
    Oct 7, 2022 at 12:14
  • 1
    <RichText.Content /> and <RichText/> are not the same component, you cannot use interactive components inside a save component. You can trivially test this by using the component and if it works then it works, if it does not then it will not, and it will be glaringly obvious that it's broken
    – Tom J Nowell
    Oct 10, 2022 at 16:40
  • 1
    This answer is given credit here: css-tricks.com/?p=374381&preview=1&_ppp=538d439169 Hopefully, you can have a look before I ask the editor to publish.
    – m4n0
    Oct 13, 2022 at 4:53

Your Answer

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

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