What is the difference between select(‘core’) vs apiFetch, and when to use which?


This is a very important architectural decision in Gutenberg — and honestly, many developers misuse both.

Let’s break it down in a practical, real-world way so you can decide like a tech lead 👇


🧠 select('core') vs apiFetch — What’s the Difference?

Featureselect('core')apiFetch
Data SourceWP Data Store (core-data)Direct REST API
Reactivity✅ Reactive (auto re-render)❌ Not reactive
Caching✅ Built-in caching❌ No caching
Performance✅ Optimized⚠️ Depends on usage
Ease of Use✅ Cleaner in blocks⚠️ More manual
Control⚠️ Limited✅ Full control

✅ When You Should Use select('core') (Recommended Most of the Time)

👉 Use this inside Gutenberg blocks/UI

✔ Best for:

  • Fetching posts, pages, users
  • Displaying dynamic data in UI
  • When you want automatic updates
  • When performance matters

Example

const posts = useSelect((select) => {
return select('core').getEntityRecords('postType', 'post');
}, []);

💡 Why it’s better

  • Uses centralized state (Redux-like store)
  • Avoids duplicate API calls
  • Auto re-renders UI when data changes
  • Works seamlessly with Gutenberg

⚠️ When apiFetch is Better

👉 Use this when you need full control or custom behavior

✔ Best for:

  • Custom REST API endpoints
  • POST / PUT / DELETE requests
  • Non-Gutenberg environments
  • One-time operations (form submit, migration scripts, etc.)

Example

import apiFetch from '@wordpress/api-fetch';const fetchData = async () => {
const posts = await apiFetch({
path: '/wp/v2/posts?per_page=5',
}); console.log(posts);
};

🚨 Common Mistake (Very Important)

❌ Using apiFetch inside React render logic:

// ❌ BAD PRACTICE
const posts = await apiFetch({ path: '/wp/v2/posts' });

👉 This causes:

  • Multiple API calls
  • No caching
  • Performance issues

⚡ Real-World Decision Rule (Use This)

👉 Ask yourself:

1. Is this UI data inside Gutenberg?

👉 ✅ Use select('core')


2. Is this a custom API or action (POST/UPDATE)?

👉 ✅ Use apiFetch


3. Do I need caching + reactivity?

👉 ✅ Use select('core')


4. Do I need full control over request?

👉 ✅ Use apiFetch


🏆 Best Practice (Senior-Level Pattern)

👉 Combine both when needed:

  • Use select('core') → for reading data
  • Use apiFetch → for writing/updating data

Example Pattern

// Read (cached + reactive)
const posts = useSelect((select) =>
select('core').getEntityRecords('postType', 'post')
);// Write (manual control)
const createPost = async () => {
await apiFetch({
path: '/wp/v2/posts',
method: 'POST',
data: { title: 'New Post' },
});
};

🧩 Bonus Insight (Interview-Level)

👉 select('core') internally:

  • Uses @wordpress/core-data
  • Wraps REST API calls
  • Adds caching + resolution tracking
  • Prevents duplicate requests

🏁 Final Verdict

👉 If you’re building Gutenberg blocks:

Use select('core') 80–90% of the time

👉 Use apiFetch only when:

  • You need custom logic
  • Or you’re mutating data

Leave a Reply

Your email address will not be published. Required fields are marked *