...

Block Notes: Generate a Reference to a Block

Block Notes: Generate a Reference to a Block

You might also like

I’m working on a block that, like many, isn’t limited to a single instance in the editor (and thus not the frontend); however, because there are certain features of the block I want to manipulate when the page loads, I want generate a reference to said block.

For example, the structure of the markup in the edit function looks something like this:

<div className="wp-acme-block"> <div className="wp-acme-block-editor"> </div> <div className="wp-acme-block-preview"> </div>
</div>

The functionality will allow the user to toggle the visibility of the editor container and the preview container. And to manage this functionality, I want to access the parent element of each one. Specifically, the one with the class wp-acme-block.


And this is easy to do with a couple of features of React:

  • useRef is a hook that allows for direct interaction with the DOM. It returns a ref object that maintains a property called current. This enables us to maintain a reference to a specific element.
  • useEffect is a hook that handles side effects in functional components. It allows us to do a lot of things (like fetching data) but also allows us to manually work with the DOM.

Given those two hooks, I can place a ref attribute on the primary container that I can then use elsewhere in the code.

First, in the header of the file add the following:

import { useRef, useEffect } from 'react';

Then at the top of the edit function, I have the following code:

edit: ({ attributes, setAttributes }) => { const blockRef = useRef(null); // ...
};

Then, in the edit function where I have the markup that I’ve shown above, I’ll add the ref attribute:

<div className="wp-acme-block" ref={blockRef}> <div className="wp-acme-block-editor"> </div> <div className="wp-acme-block-preview"> </div>
</div>

And finally, I can use this reference in the edit function before it calls return so I can refer to the element in other functions.

useEffect(() => { acmePreviewFunction(blockRef.current);
}, []);

So the full, relevant code looks like this:

import { useRef, useEffect } from 'react'; // ... registerBlockType('acme/example-block', { // ... attributes: { // ... }, edit: ({ attributes, setAttributes }) => { const blockRef = useRef(null); // ... useEffect(() => { acmePreviewFunction(blockRef.current); }, []); // ... return ( <div className="wp-acme-block" ref={blockRef}> <div className="wp-acme-block-editor"> </div> <div className="wp-acme-block-preview"> </div> </div> ); }, // ...
});

Then passing the current property as an argument to other functions, you’ve got access to the block such that you can manipulate it with other JavaScript functions.

Further, the ref will refer only to the instance of the block so it won’t manipulate other instances of the block located in the editor (or, more specifically, the DOM).

Being a Software Developer | Tom McFarlin

Being a Software Developer

Not everyone who works in software development has a degree in computer science (or a degree at all), and I’m…