This weekend I was building a block that needed to to the following:
- Access a list of items from an internal WP REST API endpoint
- Populate that list of items in a select box
Using create-block, I’d scaffolded a new block, which gave me the following code in my edit.js
file.
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __(
'Some block text',
'text-domain
) }
</p>
);
}
I then started tweaking the block structure, to support a select box, and hard coded some options:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<div { ...useBlockProps() }>
<label>
{ __(
'Select your item from the list below',
'text-domain'
) }
</label>
<select>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
</select>
</div>
);
}
Next, I imported the api-fetch package, which would handle the WP REST API request for me, and coded up a quick apiFetch
request to my internal WP REST API endpoint.
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import apiFetch from '@wordpress/api-fetch';
import './editor.scss';
export default function Edit() {
apiFetch( { path: '/collaborator/v1/teams' } ).then( ( teams ) => {
// do something with teams
} );
return (
<div { ...useBlockProps() }>
<label>
{ __(
'Select your item from the list below',
'text-domain'
) }
</label>
<select>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
</select>
</div>
);
}
So far so good, but…
Now I had a problem, I needed the apiFetch
request to happen once the block is loaded in the editor, fetch the teams
, and populate the select with the options. Because apiFetch
is a Promise-based mechanism (ie it will fetch the REST API data asynchronously, and let the rest of the code execute) I would need to trigger the update AFTER the fetch request had returned it’s response.
This reminded me of a tweet to a blog post a developer buddy of mine, Josh Pollock, had recently tweeted:
In his post, Josh explains how to use the useEffect hook with the useState to fetch some data via a REST API, and use that data to populate something in your component. Perfect for what I needed.
useEffect
can handle the fetching of the WP REST API data once the block has loadeduseState
can be used inside theapiFetch
response to update the relevant variable that populates the select box.
import React, { useState, useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import apiFetch from '@wordpress/api-fetch';
import './editor.scss';
export default function Edit() {
const [teams, setTeams] = useState([]);
useEffect(() => {
apiFetch( { path: '/collaborator/v1/teams' } ).then( ( teams ) => {
setTeams(teams);
} );
}, []);
return (
<div { ...useBlockProps() }>
<label>
{ __(
'Select your item from the list below',
'text-domain'
) }
</label>
<select>
{teams.map((team) => (
<option key={team.id} value={team.id}>
{team.name}
</option>
))}
</select>
</div>
);
}
I love how simple and clean this all is.
- By implementing the
useStat
e hook, I have theteams
variable and the associatedsetTeams
function that will update theteams
variable whenever I need to. And by doing so, and usingteams
to populate the select box, wheneverteams
is updated, the select box will be populated with the contents ofteams
. - By implemented the
useEffect
hook, it will automatically make the apiFetch request as soon as the block loads.
Special thanks go to Josh for sharing this post.
If you’re looking to work with or learn from a developer who’s way smarter than me, I recommend checking out Josh’ site at https://pluginmachine.com/.
Developers, hit publish more!
Which gets me back to the title of this post. I don’t know why Josh chose to publish this specific post, but it helped me understand a concept quickly, and be able to implement it after just reading the post through once. Josh, like myself, enjoys blogging real world solutions to problems, and there’s a huge benefit in that.
Example code in the official developer docs for a language or framework are great, but there’s no better teacher than seeing how someone implements it in a real world situation.
So if you’ve just figured out something new that you were struggling with, blog about it, share it with the rest of your community. You never know who you may help out!
Leave a Reply