openedx / openedx/frontend-app-learning
Convert Learning from redux to Context + react-query
@arbrandes is already working on this.
Since Aug 20, 2026.
- Dominant language
- JavaScript
- Stars
- 70
- Forks
- 335
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 35
Description
[!NOTE]
This issue body was generated by Claude (Claude Code) and reviewed before posting.
Summary
Convert frontend-app-learning from Redux to React Query (for server state) + React state/context (for client state), on master. This is Stage 1 of 2 on the road to frontend-base: the frontend-base port (#1905) is blocked on this work, because the frontend-base shell provides a global React Query client and does not carry Redux.
Why
- OEP-0067 ADR-0010 mandates React Query for server state and plain React state/context for client state; the older Redux ADR is superseded.
- The frontend-base migration guide is explicit: "If the MFE uses Redux, consider porting the app over to react-query, as it will make it much easier to handle header (and footer) customization."
- Doing the Redux removal first (on
master) keeps it decoupled from the toolchain swap, matching how the reference apps sequenced it.
Reference conversions
Part of the org-wide effort tracked in openedx/public-engineering#450. Both reference apps converted on master first, then forward-ported to their frontend-base branch:
- learner-dashboard #786 "React query and react context conversion" (later forward-ported in #801).
- authn #1629 "React query migration" (later forward-ported in #1641).
Scope
Learning currently has 7 store reducers, 5 local slices (~40 hand-written thunks), generic/model-store as the central normalized cache, ~104 useSelector / ~58 useDispatch sites, and only 2 connect() components. injectIntl → useIntl is already done.
The work breaks down per feature area — see the sub-issues. Test-infrastructure migration (off axios-mock-adapter / initializeTestStore, reusing Rosie factories + Pact tests) happens within each item as its own tests convert, not as a separate task.
The plugins Redux slice (generic/plugin-store, a bespoke override-method registry) is in scope here — its de-Redux is tracked in #2017. Don't confuse it with the separate @openedx/frontend-plugin-framework → frontend-base Slot migration, which is part of the Stage-2 frontend-base port (#1905).
Known blocker: @edx/frontend-lib-special-exams
@edx/frontend-lib-special-exams (^4.0.0) is itself Redux-based: it exports the specialExams reducer that learning registers in store.ts, and its components (OuterExamTimer, SequenceExamWrapper) and exam-access hooks read that slice via react-redux. Learning never touches state.specialExams itself (its own exam data lives in courseHome.examsData), so this is purely an infrastructure coupling.
What is and isn't blocked. Learning's own internal conversion — including reducing the store to specialExams-only (#1978) — is not blocked by the library; it depends only on learning's remaining Stage-1 work. What waits on the library is the final step: dropping react-redux / redux / @reduxjs/toolkit from learning's package.json (and deleting store.ts / AppProvider store=), because those exam components need a react-redux Provider + store somewhere above them, and frontend-base's SiteProvider supplies neither.
The required library change is not necessarily a full React Query rewrite. Two options: (A) make the library self-contained — it ships its own store and wraps its exported components in their own Provider, so consumers register nothing (redux becomes transitive-only for consumers); or (B) convert the library to React Query. These are being evaluated in #2018 before any decision; nothing is filed on frontend-lib-special-exams until that investigation settles on a concrete approach.
The full phase-by-phase plan is in the first comment below; a progress review + the courseware decomposition are in a later comment.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.