What is WordPress Data?

This entry is part 2 of 15 in the series, A Practical Overview of the @wordpress/data API

The WordPress data module (or package) is a critical component of the new WordPress Editor as demonstrated by it’s implementation in (at the time of writing) 7 other WordPress packages:

  • @wordpress/block-directory registers a store with the core/block-directory namespace.
  • @wordpress/block-editor registers a store with the core/block-editor namespace.
  • @wordpress/blocks registers a store with the core/blocks namespace.
  • @wordpress/core-data registers a store with the core namespace.
  • @wordpress/edit-post registers a store with the core/edit-post namespace.
  • @wordpress/editor registers a store with the core/editor namespace.
  • @wordpress/notices registers a store with the core/notices namespace.

What do I mean by “namespace” in the above list?
We’ll get into this in more detail later on, but as a quick answer, wp.data stores can be registered to their own state object identified by a given string which is referred to here as their namespace. So to interact with the data stored in a given state, you need to know and reference it’s namespace.

So what is wp.data and why was it created? From the guide is the following description:

WordPress’ data module serves as a hub to manage application state for both plugins and WordPress itself, providing tools to manage data within and between distinct modules. It is designed as a modular pattern for organizing and sharing data: simple enough to satisfy the needs of a small plugin, while scalable to serve the requirements of a complex single-page application.

The data module is built upon and shares many of the same core principles of Redux, but shouldn’t be mistaken as merely Redux for WordPress, as it includes a few of its own distinguishing characteristics.

I’m going to pull a few key words and phrases from this description and zero in on them.

Application State and Tools

In any given application, there are various contexts where state comes in to play.  Typically, when the term state is used, it refers to a snapshot of a set of data that is being used by something in the application at a given point of time.  

So in our given product directory example we’re going to be using through this series, state could refer to the current list of products available for displaying to the potential customer at the time they load that initial view of products.

In React, there are various contexts in which you might find state:

Local State:

This is typically at the component level and it deals with state only that particular component cares about. Typically nothing outside that component cares about that state.

Tree State:

This is the state that relates to a slice of a given React component tree.  Typically in this setup you’ll have a parent component that maintains the state for all its children and passes that state through via props or react context.

Sidenote: Tree state isn’t a term you’ll find referenced much elsewhere and is often considered the same as local state. I find it helpful however to differentiate between state that is specific to a component vs state that lives across a react tree (but isn’t global). But in most react/redux documentation you’ll only find two types of state referenced: Local and Global (or application).

Application State:

Application state is sometimes referred to as a “global” state and it lives outside of the rendered component tree. Components interact with this state via whatever interface is exposed to the components for doing so.

This might be in the form of a simple global object, or something like Redux and MobX.

WordPress data is a form of application state. It exposes various interfaces (or tools) for both creating and maintaining this application state. We’ll take a closer look at those various tools (which we’ll refer to as it’s api) in later posts.

Modular Pattern

There are two aspects to the modular pattern used in wp.data: it is published as it’s own package, and the pattern for how stores are registered and consumed.

As a published package, wp.data can be consumed by any code needing it without bringing in the weight of any additional stores. Yet, via it’s apis any registered store states can be interacted with via a common interface.

Stores are registered and consumed individually yet can be interdependent within the same registry. So for instance, an application can consume selectors or actions from any registered store (or even cross stores within their own selectors or actions).

Further, later in this series, I’ll spend a bit of time introducing how you can create your own wp.data registry that inherits from a parent which allows for having descendant modular registries in use within a react component tree!

Share same core principles of Redux

WordPress data shares three basic principles with Redux with some slight variations in some cases:

Single source of truth

This principle in redux is:

The state of your whole application is stored in an object tree within a single store.

This principle diverges a bit in wp.data in that you may have multiple namespaced stores kept within a given registry.  So each store has its own state tree. Generally, it’s also a best practice to keep the state for a store serializable. Don’t put anything inside it that you can’t easily turn into JSON.

State is read-only

The only way to change the state is to emit an action, an object describing what happened.

What this means is you don’t ever mutate state but instead dispatch action objects that help describe the intent for transforming the state.

Changes are made with pure functions 

To specify how the state tree is transformed by actions, you write pure reducers.

The registered reducer for a given store should be a pure function that receives the previous state and action and returns the next state.  The reducer should not perform any side-effects and should never mutate the state. It either returns the existing state (if there are no changes) or a new state object (having changes incorporated in it).

Distinguishing Characteristics

While wp.data has a lot of similarities with redux including the way parts of the API are named (selectors, action creators, reducer etc), there are still some key differences that are notable.

Modularization Pattern

In redux, there is generally only one global state.  In wp.data, you can isolate slices of state to a namespaced store which has the following impacts:

  • Dispatched actions only surface in the reducer for the store they apply to.
  • Subscribers fire on changes to any registered store state within the given registry.  This is because it is possible that implementing code may be selecting from multiple registered stores in a subscriber callback.

Separation of mapStateToProps from mapDispatchToProps

In React Redux, these two mapping functions are combined in the connect api, whereas in wp.data there is a clear distinction via the usage of withSelect and withDispatch (or the siblings useSelect and useDispatch).  In wp.data, dispatch is not dependent on a subscription to state changes and this allows for state-derived values to be used. With that said, it’s still possible to dispatch actions in withSelect or useSelect.

Subscribe is only called when the state has changed.

In Redux, a subscribe listener callback is called on every dispatch, regardless of whether the value of the state has changed or not.  In wp.data, a subscriber is only called when the state has changed.

Select mapping function can return undefined if it has no props to inject.

In React Redux, the mapStateToProps function must return an object.  In wp.data, a withSelect mapping function can return undefined if it has no props to inject.

Also, in React Redux, the mapDispatchToProps argument can be defined as an object or a function. In wp.data, the withDispatch higher-order component creator must be passed a function.

In the next post in this series we’re going to start diving into the wp.data api for registering a store!

Series NavigationWordPress Data Series Overview and IntroductionWordPress Data: How to Register a Custom Store

Leave a Reply

Up Next:

WordPress Data Store Properties: Reducer

WordPress Data Store Properties: Reducer