wp.apiFetchを用いた投稿データの取得と更新・削除する方法

WordPress の JavaScript API である wp.apiFetchを用いると、投稿データやユーザデータの取得・更新・削除が行えます。その使い方とstoreとの違いを見ていきます。

wp.apiFetchの特徴

  • 認証が必要なエンドポイントもある
  • 認証情報(nonce)を自動で使用
  • パスに /wp-json は不要。wp.apiFetch({ path: '/wp/v2/posts' }) で OK。(内部で /wp-json が付加される)
  • ページネーションは ?page=2 などでページ指定できる。(per_page の最大は 100)
  • useEffect で囲う形でを使う。apiFetch は「非同期」だが、コンポーネントの初期表示後に API を呼び出したいため。
  • useState を使うことで、状態が変わったときに UI を自動更新する。非同期データ(例:apiFetch のレスポンス)は、useState に入れるのが標準的

wp.apiFetchとstoreの違い

wp.apiFetchと@wordpress/data(store)の違いをまとめます。

項目wp.apiFetch@wordpress/data
データ取得元REST API 直接呼び出し内部ストア(キャッシュ+状態管理)
再取得手動(毎回fetch)自動(再レンダリングで再取得)
書き込み操作POST, PUT, DELETE 可能書き込みは基本できない
状態管理なし(ステート管理は自分で)Reactと連携された状態管理あり
向いている用途投稿作成・更新・外部連携など編集画面でのリアクティブな表示

投稿を表示したいだけならstore、投稿を更新したいならwp.apiFetchを使う。

目的使うべき
投稿やメタを「取得して表示だけ」したいselect('core')(store)
投稿を「新規作成・更新・削除」したいwp.apiFetch
最新データを必ず取得したい(キャッシュ無視)wp.apiFetch
エディタ内でデータ変更に自動追従したいstoreuseSelect
外部APIとの連携が必要wp.apiFetch(fetch相当)

wp.apiFetchでデータを取得する場合

wp.apiFetch({ path: '/wp/v2/posts' })
  .then((posts) => {
    console.log(posts); // 投稿の配列が表示される
  })
  .catch((error) => {
    console.error('投稿の取得に失敗しました:', error);
  });

path

  • WordPress REST API のパスを指定。最後のスラッシュはとくに不要
  • 例1:/wp/v2/posts → 投稿一覧
  • 例2:/wp/v2/posts/123 → 投稿ID 123 の詳細

method(省略時は GET)

  • デフォルトで GET メソッドが使われる。
  • POST、PUT、DELETE なども利用可能

特定の投稿IDの投稿データを取得する

import { useEffect, useState } from "@wordpress/element";

export default function Edit() {
	const [post, setPost] = useState(null);

	useEffect(() => {
		wp.apiFetch({ path: "/wp/v2/posts/298" })
			.then((data) => setPost(data))
			.catch((err) => console.error("投稿取得失敗", err));
	}, []); // ← [] があるので初回だけ実行される

	return (
		<div>
			<ul>
				<li>{post ? post.title.rendered : "読み込み中..."}</li>
			</ul>
		</div>
	);
}

投稿一覧を条件付きで取得する

export default function Edit() {
	const [posts, setPosts] = useState([]); // 複数投稿を取得するため配列を渡して初期化

	useEffect(() => {
		wp.apiFetch({ path: "/wp/v2/posts?per_page=5" })
			.then((data) => setPosts(data))
			.catch((err) => console.error("投稿取得失敗", err));
	}, []); // ← [] があるので初回だけ実行される

	return (
		<div>
			<ul>
				{posts.map((post) => (
					<li key={post.id}>{post ? post.title.rendered : "読み込み中..."}</li>
				))}
			</ul>
		</div>
	);
}

カテゴリーで絞り込む

export default function Edit() {
	const [posts, setPosts] = useState([]); // 複数投稿を取得するため配列を渡して初期化

	useEffect(() => {
		wp.apiFetch({ path: "/wp/v2/posts?categories=1" })
			.then((data) => setPosts(data))
			.catch((err) => console.error("投稿取得失敗", err));
	}, []); // ← [] があるので初回だけ実行される

	return (
		<div>
			<ul>
				{posts.map((post) => (
					<li key={post.id}>{post ? post.title.rendered : "読み込み中..."}</li>
				))}
			</ul>
		</div>
	);
}

投稿を検索する(キーワード検索)

import { useEffect, useState } from "@wordpress/element";

export default function Edit() {
	const [posts, setPosts] = useState([]); // 複数投稿を取得するため配列を渡して初期化

	useEffect(() => {
		wp.apiFetch({ path: "/wp/v2/posts?search=abc" })
			.then((data) => setPosts(data))
			.catch((err) => console.error("投稿取得失敗", err));
	}, []); // ← [] があるので初回だけ実行される

	return (
		<div>
			<ul>
				{posts.map((post) => (
					<li key={post.id}>{post ? post.title.rendered : "読み込み中..."}</li>
				))}
			</ul>
		</div>
	);
}

wp.apiFetchで投稿データを更新

POST メソッドで 投稿 ID を含む /wp/v2/posts/123 に送信すると既存投稿の更新になる。

export default function Edit() {
	wp.apiFetch({
		path: "/wp/v2/posts/386",
		method: "POST",
		data: {
			title: "新しいタイトル",
			content: "新しいコンテンツ",
			status: "publish",
		},
	})
		.then((updatePost) => {
			console.log("更新成功:", updatePost);
		})
		.catch((err) => {
			console.error("投稿更新エラー:", err);
		});
}

wp.apiFetchで新規投稿を作成

POST メソッドで 投稿 ID を含まない /wp/v2/posts に送すると新規作成になる。

export default function Edit() {
	wp.apiFetch({
		path: "/wp/v2/posts",
		method: "POST",
		data: {
			title: "新しいタイトル",
			content: "新しいコンテンツ",
			status: "publish",
		},
	})
		.then((updatePost) => {
			console.log("投稿作成成功:", updatePost);
		})
		.catch((err) => {
			console.error("投稿作成エラー:", err);
		});
}

wp.apiFetchで既存の投稿を削除

DELETE メソッドで 投稿 ID を含む /wp/v2/posts/123 に送信すると既存投稿の削除になる。

export default function Edit() {
	wp.apiFetch({
		path: "/wp/v2/posts/389",
		method: "DELETE",
		data: {
			title: "新しいタイトル",
			content: "新しいコンテンツ",
			status: "publish",
		},
	})
		.then((updatePost) => {
			console.log("削除成功:", updatePost);
		})
		.catch((err) => {
			console.error("削除エラー:", err);
		});
}

フロントエンドをJavaScriptで実装する

save.js

export default function save() {
	return (
		<div className="my-api-fetch-block-frontend">
			<p>投稿を読み込み中...</p>
		</div>
	);
}

vies.js

document.addEventListener("DOMContentLoaded", () => {
	const container = document.querySelector(".my-api-fetch-block-frontend");

	if (!container) return;

	fetch("/wp-json/wp/v2/posts?per_page=5")
		.then((res) => res.json())
		.then((posts) => {
			const ul = document.createElement("ul");
			posts.forEach((post) => {
				const li = document.createElement("li");
				li.innerHTML = post.title.rendered;
				ul.appendChild(li);
			});

			container.innerHTML = "<h3>最新の投稿</h3>";
			container.appendChild(ul);
		})
		.catch((err) => {
			container.innerHTML = "<p>投稿の取得に失敗しました。</p>";
			console.error(err);
		});
});