Saad Tarhi

Open Source • Professional

WooCommerce Data Store Migration

Converting React Context to WordPress Data Stores

Challenge: WooCommerce Blocks relied on fragile React Context for critical checkout state.

Solution: Migrated the architecture to WordPress Data Stores with typed selectors, actions, and a safe rollout workflow.

Result: Third-party integrations gained a stable API surface and regressions decreased.

  • React
  • Redux
  • TypeScript
  • WordPress
  • WooCommerce Blocks
Architectural diagram showing state management migration
Migration from React Context to WordPress Data Stores (@wordpress/data)

Context

Improving Extensibility for a Critical WordPress Plugin

Why this work mattered and the environment it lived in.

WooCommerce Blocks initially relied heavily on React Context for managing front-end state. While functional, this approach presented significant challenges for extensibility, making it difficult for third-party developers (e.g., payment gateway creators) to reliably access or react to crucial state changes within the blocks. This limitation hindered the ecosystem and led to support issues, such as accessing payment readiness state (canMakePayment). A major architectural refactoring was needed to improve state accessibility and align with broader WordPress development patterns.
Full background
The goal was to migrate the core state management of WooCommerce Blocks from React Context to WordPress Data Stores (@wordpress/data, which is built upon Redux principles). This aimed to create a centralized, observable, and extensible state accessible to both internal components and third-party plugins, while carefully preserving the integrity of sensitive data flows, particularly around payments.

Snapshot

Highlights, Challenges, Skills

A concise readout for quick evaluators.

Highlights

  • Successfully migrated critical payment state to a more extensible architecture
  • Innovated review process for large architectural changes through sequential PRs
  • Maintained backward compatibility for third-party plugin developers

Challenges

  • Deciphering complex legacy code with intertwined state and event systems
  • Maintaining backward compatibility while completely changing the underlying architecture
  • Finding effective ways to review massive code changes without compromising quality

Skills Demonstrated

  • React & Redux: Deep understanding of state management patterns
  • WordPress Data Stores: Working with @wordpress/data implementation
  • TypeScript: Adding type safety to a complex JavaScript codebase

Role

My Role & Contributions

I joined a team of three highly proficient engineers working on this complex and sensitive migration shortly after returning from an extended break. Despite the challenge of rapidly onboarding onto an ongoing, intricate project, I quickly integrated and became a key contributor. My role combined technical implementation with process innovation to address a significant workflow challenge.
  • Core Migration Implementation: Migrated critical functionality, focusing on the PaymentMethodDataProvider
  • Collaborative Problem Solving: Engaged in technical discussions to navigate challenges like deciphering complex legacy code
  • Innovated PR Review Workflow: Identified and solved a major bottleneck in reviewing large-scale architectural changes
  • Migration Strategy: Created a stepwise approach to ensure data integrity throughout the refactoring process
  • Technical Documentation: Documented new patterns for other developers to follow in subsequent migrations
  • Cross-team Coordination: Communicated architecture changes to payment gateway developers

Key Contributions

Key Contributions

Open narratives that explain the impact of each slice of work.

Contribution 01

Migration of Critical Payment State

Refactoring sensitive payment state logic while preserving functionality

The most challenging part of the migration involved the PaymentMethodDataProvider, which managed critical payment processing state in the checkout flow. This component controlled sensitive payment data and was integrated with numerous payment gateways via a complex event system.

I carefully refactored this system by:
  • Creating a new WordPress Data Store structure for payment data
  • Mapping existing context methods to store selectors and actions
  • Implementing selector and action functions for accessing and modifying payment state
  • Ensuring backward compatibility for existing integrations
  • Adding robust TypeScript types for improved code safety
This was particularly delicate work as payment processing is mission-critical for e-commerce sites, and any regressions could directly impact merchants' ability to collect payments.
Architectural diagram showing before the migration from the React Context
Migration architecture: React Context
Architectural diagram showing after the migration to Data Store
Migration architecture: WordPress Data Store

Contribution 02

Innovative PR Review Workflow

Created a sequential PR workflow to make large architectural changes reviewable

I identified a major bottleneck: the unavoidable creation of massive PRs with huge file changes, making thorough reviews extremely difficult and risky for this sensitive refactoring.
To make the migration of complex and sensitive state (specifically, the PaymentMethodDataProvider) to a WordPress Data Store reviewable and manageable for code reviewers, I designed and implemented an innovative sequential PR workflow.

Instead of creating a single, massive pull request—which would be difficult and risky to review—I broke the migration into a logical series of dependent, incremental PRs. Each PR focused on a well-defined, self-contained aspect of the migration and kept the application functional and testable at each stage.

For the PaymentMethodDataProvider migration, the steps were:
  1. Rebase & Fix Failed Payments (PR #6587):

    Integrated the latest branch changes and refactored status update logic so payment status is consistently read/written from the new WordPress Data Store, replacing legacy context usage for status updates.

  2. Set/Get Provider State from Store (PR #6588):

    Updated the provider logic to fully use the data store (instead of useReducer and React context) for all state and dispatch logic, enabling the legacy provider to delegate all state access to the data store.

  3. Get Data Directly from Store (PR #6589):

    Removed the indirection via context—updated the remaining code that relied on the provider/context to reference the data store directly, ensuring all state consumers and hooks access data from a single, centralized store.

  4. Refactor Store & Context (PR #6607):

    Cleaned up legacy code: removed unused React context, hooks, and files, migrated all relevant side effects and event-based logic to Redux thunks within the store, and finalized the switch to a pure store-based approach.


Each PR was reviewed, tested, and merged sequentially into a dedicated feature branch, which was then merged into the main branch after the series was complete.

This approach was praised by tech leads and adopted by the team for subsequent large-scale changes, significantly reducing risk and improving code review quality.
Diagram of sequential PR workflow
Sequential PR workflow for large architectural changes

Contribution 03

Redux-based WordPress Data Store Implementation

Creating a centralized, observable state with Redux principles

The WordPress Data Store system (@wordpress/data) is built on Redux principles but adapted for the WordPress ecosystem. I implemented several data stores following these principles:
  • Clear Separation of Concerns: Actions for state changes, selectors for data retrieval
  • Immutable State Management: Ensuring predictable state updates
  • Observable State: Allowing third-party plugins to subscribe to state changes
  • Side-effect Management: Handling asynchronous operations in a predictable manner
This implementation provided a clean API for both internal components and external plugins to interact with, significantly improving the extensibility of the WooCommerce Blocks system.
export const config = {
  reducer,
  selectors,
  actions,
  controls: { ...dataControls, ...sharedControls }, // Combine internal and WP controls
  __experimentalUseThunks: true, // Enable async side effects (e.g., fetch)
};
 
// Create the Redux-style data store
const store = createReduxStore(STORE_KEY, config);
 
// Register the store in the global WP registry
register(store);

Technical Deep Dive

Technical Architecture & Migration Strategy

The migration from React Context to WordPress Data Stores required careful planning and execution:

State Mapping Strategy: The first challenge was mapping the existing React Context API to the WordPress Data Store paradigm. This involved creating appropriate selectors (getters) and actions (setters) that matched the existing API surface while taking advantage of the new architecture. We created a consistent pattern that:
  • Preserved API naming where possible to minimize changes
  • Added TypeScript interfaces for improved type safety
  • Maintained backward compatibility for third-party developers
  • Enhanced documentation for new usage patterns


Event System Refactoring: The existing system used a custom event emitter pattern that needed to be refactored to work with the Data Store. I replaced this with Redux-style actions and subscribers, which provided better type safety and predictability.

Growth

Key Takeaways

  • Mastered techniques for safely refactoring large-scale state management systems
  • Developed deep understanding of WordPress data flow and extensibility patterns
  • Learned effective strategies for breaking down complex migrations into reviewable units
  • Gained experience with gradual migration patterns that maintain backward compatibility
  • Strengthened ability to quickly onboard to complex projects and contribute effectively
  • Improved collaborative development skills when working with sensitive, mission-critical code

Toolkit

Technologies Used

Core Stack

  • React
  • WordPress Data (@wordpress/data)
  • Redux (architecture principles)
  • TypeScript
  • JavaScript (ES6+)

Libraries

  • WooCommerce Blocks
  • WordPress Packages
  • Jest (testing)

Tools

  • GitHub
  • GitHub Actions
  • WordPress Plugin Development Tools
  • Webpack