Implementing Resolvers for Data Fetching in WordPress @wordpress/data
Learn how to implement resolvers in @wordpress/data to automate API data fetching. Discover how to sync your React state with the WordPress REST API seamlessly.
Previously in this course, we covered Registering a Custom Data Store in WordPress @wordpress/data and learned how to build Writing Selectors for Data Access: Memoization in WordPress. While selectors allow us to query the state, they are passive—they only return what is currently in memory.
In this lesson, we introduce resolvers, the mechanism that makes your data layer proactive. A resolver detects when requested data is missing from the store and automatically triggers an API request to fetch it.
Understanding Resolvers from First Principles
In the @wordpress/data architecture, a resolver is a special function associated with a selector. When you call a selector from a component, the data registry checks if the requested data exists. If it doesn't, the registry executes the corresponding resolver.
This creates a "lazy loading" pattern for your plugin data. Your React components don't need to manually orchestrate useEffect hooks to fetch data on mount; they simply ask for the data they need, and the store handles the heavy lifting of fetching it if it’s absent.
Implementing a Resolver for the Knowledge Base
To implement a resolver, we add a resolvers object to our createReduxStore configuration. Let's extend our Knowledge Base plugin to fetch articles automatically.
1. The Resolver Logic
We'll create a resolver that targets a specific article by its ID. If the article isn't in our store, the resolver will call our service layer (which we built in Building the Knowledge Base Service Layer).
JAVASCRIPT// store/resolvers.js import { receiveArticles } from CE9178">'./actions'; import { apiFetchArticles } from CE9178">'../services/api'; export const resolvers = { getArticle(id) { return { type: CE9178">'RESOLVE_ARTICLE', id, }; }, }; // We handle the side effect in a generator function export const controls = { RESOLVE_ARTICLE: ({ id }) => apiFetchArticles(id), }; export const resolversGenerators = { *getArticle(id) { const article = yield { type: CE9178">'RESOLVE_ARTICLE', id }; yield receiveArticles([article]); } };
2. Registering the Resolver
When you register your store, you pass the resolvers object alongside your actions and selectors. The registry maps the selector getArticle to the resolver getArticle.
JAVASCRIPT// store/index.js import { createReduxStore, register } from CE9178">'@wordpress/data'; import { reducer } from CE9178">'./reducer'; import * as selectors from CE9178">'./selectors'; import * as actions from CE9178">'./actions'; import { resolvers } from CE9178">'./resolvers'; const store = createReduxStore(CE9178">'my-plugin/knowledge-base', { reducer, selectors, actions, resolvers, }); register(store);
How the Flow Works
- Component Request: Your component calls
useSelect(select => select('my-plugin/knowledge-base').getArticle(123)). - Registry Check: The registry checks if
getArticle(123)is in the store. - Resolution: If missing, the registry executes the
getArticleresolver. - Action Dispatch: The resolver fetches the data and dispatches a
receiveArticlesaction to populate the store. - Re-render: Once the store updates, the selector returns the fresh data, and your component re-renders automatically.
Hands-on Exercise
Your task is to implement a resolver for the getArticles selector in your Knowledge Base dashboard.
- Modify your
resolvers.jsto include agetArticles()function. - Ensure the generator yields an API request to your REST endpoint.
- Dispatch an action (like
receiveArticles) to update the store with the fetched response. - Verify in the browser console (using
wp.data.select('my-plugin/knowledge-base').getArticles()) that the data populates the store after the initial empty state.
Common Pitfalls
- Infinite Loops: Ensure your resolver dispatches an action that eventually satisfies the selector. If the resolver fetches data but fails to update the store, the registry will keep triggering the resolver, causing an infinite loop of API requests.
- Ignoring Loading States: Resolvers happen in the background. Your UI should still handle "loading" states by checking if the data is currently being fetched (you can track this in your store state).
- Over-fetching: Only use resolvers for data that is unique to the selector. If you have a massive dataset, consider pagination within your resolver logic.
Recap
Resolvers transform your data layer from a static cache into a self-filling system. By defining them in your store, you abstract away the complexity of API management from your UI components, keeping your React code clean and declarative.
Up next: Optimizing Performance with Selectors, where we will look at how to ensure our components don't re-render unnecessarily when the store updates.
Work with me

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.