カスタムブロックの更新時に何かするときのメモ

繰り返し使うカスタムブロックにおいて、以前の属性(設定)を読み出すような仕組みを実装できないか考えた。当初は編集中に属性が変わったことをuseEffectで捉え、その度に独自のREST APIで更新していたが、この方法では更新頻度が多くなり、更新頻度を少なくする方法を検討してみた。

更新頻度を下げるには

useEffectよりも更新頻度を下げるために思いついたのが、投稿を更新するタイミング。このタイミングで確実に処理できるのがベストと思い、ChatGPTに『WordPressのカスタムブロックで投稿の「更新」時に何らかの処理を行う場合はどうすれば良いでしょうか。』と質問してみた。

少しやりとりしながら教えてもらったJavaScript部分は以下のような内容だった(要所に空白を入れたもの)。

const { subscribe } = wp.data;

let lastIsSavingPost = wp.data.select( 'core/editor' ).isSavingPost();

subscribe( () => {
	const isSavingPost = wp.data.select( 'core/editor' ).isSavingPost();
	const isAutosavingPost = wp.data.select( 'core/editor' ).isAutosavingPost();
	if ( lastIsSavingPost && ! isSavingPost && ! isAutosavingPost ) {
		const blocks = select( 'core/block-editor' ).getBlocks();
		blocks.forEach( block => {
			if ( 'ブロック名' === block.name ) {

				// 処理

			}
		} );
	}
	lastIsSavingPost = isSavingPost;
} );

1行目の記述が見慣れなかったので、ちょっと質問したところ『古いバージョンのWordPress Gutenbergで使用されていた方法です。』とのこと。今は次のような記述で問題ないらしい。

import { subscribe, select } from '@wordpress/data';

上記のコードのポイントが、subscribe。さまざまな状態が変化するたびに呼び出されるリスナー関数を登録している。そしてリスナー関数内では次のメソッドを使って状態を判別している。

  • isSavingPost()
    投稿が保存中の場合はtrue
  • isAutosavingPost()
    投稿が自動保存中の場合はtrue

ここでわからなかったのが、直接isSavingPost()の返り値を比較せずに一旦lastIsSavingPostに保存。リスナー関数が次回以降呼び出されたタイミングで目的の処理を行うようになっていること。気になったので、isAutosavingPost()の後に次の1文を追加する。

console.log( lastIsSavingPost, isSavingPost, isAutosavingPost );

プラグインをビルドし、投稿編集画面で「更新」ボタンを押す。コンソールには次のようなログが流れた。

false false false
false false false
false true false
true true false
true true false
true true false
true false false
false false false
false false false
false false false

真ん中のisSavingPostの値は4回連続でtrueになっており、このことを考慮してlastIsSavingPostに保存し、次回以降で投稿の保存完了を判定してるようだ。

またログを見ながらisAutosavingPost()の判定は不要だと思ったので、最終形は次のようにした。

import { subscribe, select } from '@wordpress/data';

let lastIsSavingPost = false;

subscribe( () => {
	const isSavingPost = select( 'core/editor' )?.isSavingPost();
	if ( lastIsSavingPost && ! isSavingPost ) {
		const blocks = select( 'core/block-editor' ).getBlocks();
		blocks.forEach( block => {
			if ( 'ブロック名' === block.name ) {

				// 処理

			}
		} );
	}
	lastIsSavingPost = isSavingPost;
} );

これにより、投稿の更新時にカスタムブロックの設定内容を保存できた。ChatGPTと対話と動作確認を繰り返し、意図したように動作できるようになるのはいい。

【更新】2024.07.13 select( 'core/editor' )の後に「?」を追加し、限定的な状況でのエラーに対応。


最終更新 : 2024年07月13日 16:06

お勧め

get_next_image_link(2021年7月25日 更新)

string get_next_image_link( [ string | int[] $size = 'thumbnail' [ , string | false $text = false ] ] )
次の添付ファイルへのリンクを取得する。

wp_after_insert_post(2020年12月11日 更新)

void wp_after_insert_post( int | WP_Post $post, bool $update, WP_Post $post_before )
投稿情報を保存した後にアクションを実行する。

wp_save_post_revision(2024年1月10日 更新)

int | WP_Error | void wp_save_post_revision( int $post_id )
現状の投稿のリビジョンを作成する。

wp_debug_backtrace_summary(2012年6月15日 更新)

mixed wp_debug_backtrace_summary( [ string $ignore_class = null [ , int $skip_frames = 0 [ , bool $pretty = true ] ] ] )
デバッグ用の呼び出し情報を取得する。

nocache_headers(2018年5月27日 更新)

void nocache_headers( )
ブラウザのキャッシュを無効にするHTTPヘッダーを出力する。