From 08cbdab2a1b7f3e5de8f8b9994ad13a7e19694af Mon Sep 17 00:00:00 2001
From: Joel Jeremy Marquez <joeljeremy.marquez@gmail.com>
Date: Mon, 12 Feb 2024 07:07:44 -0800
Subject: [PATCH] Hooks for frequently made operations (#2293)

* Hooks for frequently made operations

* Release notes

* Fix typecheck errors

* Remove useGlobalPrefs

* Add null checks

* Fix showCleared pref

* Add loaded flag for categories, accounts and payees state

* Refactor to reduce unnecessary states

* Fix eslint errors

* Fix hooks deps

* Add useEffect

* Fix typecheck error

* Set local and global pref hooks

* Fix lint error

* VRT

* Fix typecheck error

* Remove eager loading

* Fix typecheck error

* Fix typo

* Fix typecheck error

* Update useTheme

* Typecheck errors

* Typecheck error

* defaultValue

* Explicitly check undefined

* Remove useGlobalPref and useLocalPref defaults

* Fix default prefs

* Default value

* Fix lint error

* Set default theme

* Default date format in Account

* Update packages/desktop-client/src/style/theme.tsx

Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>

---------

Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
---
 ...with-budgeted-amounts-1-chromium-linux.png | Bin 25638 -> 24585 bytes
 ...with-budgeted-amounts-2-chromium-linux.png | Bin 26212 -> 24829 bytes
 .../desktop-client/src/components/App.tsx     |  47 +--
 .../src/components/BankSyncStatus.tsx         |   7 +-
 .../src/components/FinancesApp.tsx            |  41 +--
 .../src/components/LoggedInUser.tsx           |   7 +-
 .../src/components/ManageRules.tsx            |  23 +-
 .../src/components/MobileWebMessage.tsx       |  20 +-
 .../desktop-client/src/components/Modals.tsx  |  39 +-
 .../src/components/Notifications.tsx          |  11 +-
 .../src/components/PrivacyFilter.tsx          |   3 +-
 .../src/components/ThemeSelector.tsx          |  11 +-
 .../src/components/Titlebar.tsx               |  36 +-
 .../src/components/UpdateNotification.tsx     |  12 +-
 .../src/components/accounts/Account.jsx       |  57 ++-
 .../components/accounts/AccountSyncCheck.jsx  |   3 +-
 .../src/components/accounts/Header.jsx        |   7 +-
 .../src/components/accounts/MobileAccount.jsx |  34 +-
 .../components/accounts/MobileAccounts.jsx    |  37 +-
 .../autocomplete/AccountAutocomplete.tsx      |   4 +-
 .../autocomplete/PayeeAutocomplete.tsx        |  10 +-
 .../components/budget/BudgetCategories.jsx    |  68 +++-
 .../src/components/budget/BudgetTable.jsx     |  70 ++--
 .../components/budget/DynamicBudgetTable.tsx  |  14 +-
 .../src/components/budget/MobileBudget.tsx    |  26 +-
 .../components/budget/MobileBudgetTable.jsx   |  40 +-
 .../components/budget/MonthCountSelector.tsx  |   2 +-
 .../src/components/budget/index.tsx           | 347 +++++-------------
 .../budget/rollover/RolloverContext.tsx       |   3 -
 .../src/components/filters/AppliedFilters.tsx |   2 +-
 .../src/components/filters/FiltersMenu.jsx    |   8 +-
 .../src/components/modals/CloseAccount.tsx    |  13 +-
 .../modals/ConfirmCategoryDelete.tsx          |  16 +-
 .../src/components/modals/EditField.jsx       |  12 +-
 .../src/components/modals/EditRule.jsx        |   7 +-
 .../components/modals/ImportTransactions.jsx  |   9 +-
 .../src/components/modals/LoadBackup.jsx      |  13 +-
 .../components/modals/MergeUnusedPayees.jsx   |   7 +-
 .../modals/SelectLinkedAccounts.jsx           |   3 +-
 .../components/modals/SwitchBudgetType.tsx    |   9 +-
 .../payees/ManagePayeesWithData.jsx           |   3 +-
 .../src/components/reports/Overview.jsx       |   4 +-
 .../components/reports/graphs/AreaGraph.tsx   |   2 +-
 .../components/reports/graphs/BarGraph.tsx    |   2 +-
 .../reports/graphs/CashFlowGraph.tsx          |   2 +-
 .../reports/graphs/StackedBarGraph.tsx        |   2 +-
 .../reports/reports/CustomReport.jsx          |  30 +-
 .../components/reports/reports/NetWorth.jsx   |   4 +-
 .../reports/spreadsheets/filterEmptyRows.ts   |   2 +-
 .../spreadsheets/grouped-spreadsheet.ts       |   2 +-
 .../src/components/rules/ScheduleValue.tsx    |   9 +-
 .../src/components/rules/Value.tsx            |  19 +-
 .../schedules/DiscoverSchedules.tsx           |   8 +-
 .../components/schedules/ScheduleDetails.jsx  |  12 +-
 .../components/schedules/SchedulesTable.tsx   |  21 +-
 .../src/components/select/DateSelect.tsx      |  14 +-
 .../select/RecurringSchedulePicker.jsx        |  18 +-
 .../src/components/settings/Encryption.tsx    |   9 +-
 .../src/components/settings/Experimental.tsx  |  20 +-
 .../src/components/settings/Export.tsx        |  12 +-
 .../src/components/settings/Format.tsx        |  44 +--
 .../src/components/settings/Global.tsx        |  13 +-
 .../src/components/settings/Reset.tsx         |   9 +-
 .../src/components/settings/Themes.tsx        |  10 +-
 .../src/components/settings/index.tsx         |  22 +-
 .../src/components/sidebar/Accounts.tsx       |  86 ++---
 .../src/components/sidebar/Sidebar.tsx        | 208 +++++++----
 .../components/sidebar/SidebarProvider.tsx    |  52 +++
 .../components/sidebar/SidebarWithData.tsx    | 181 ---------
 .../src/components/sidebar/index.tsx          |  77 +---
 .../transactions/MobileTransaction.jsx        |  16 +-
 .../transactions/SimpleTransactionsTable.jsx  |  18 +-
 .../src/components/util/DisplayId.tsx         |  55 ++-
 .../src/components/util/GenericInput.jsx      |   5 +-
 .../desktop-client/src/hooks/useAccount.ts    |   8 +
 .../desktop-client/src/hooks/useAccounts.ts   |  20 +
 .../src/hooks/useBudgetedAccounts.ts          |  14 +
 .../desktop-client/src/hooks/useCategories.ts |  23 +-
 .../src/hooks/useClosedAccounts.ts            |  11 +
 .../desktop-client/src/hooks/useDateFormat.ts |   7 +
 .../src/hooks/useFailedAccounts.ts            |   7 +
 .../src/hooks/useFeatureFlag.ts               |  17 +-
 .../desktop-client/src/hooks/useGlobalPref.ts |  27 ++
 .../desktop-client/src/hooks/useLocalPref.ts  |  27 ++
 .../desktop-client/src/hooks/useLocalPrefs.ts |   7 +
 .../src/hooks/useOffBudgetAccounts.ts         |  14 +
 packages/desktop-client/src/hooks/usePayee.ts |   8 +
 .../desktop-client/src/hooks/usePayees.ts     |  20 +
 .../src/hooks/usePrivacyMode.ts               |   9 +
 .../desktop-client/src/hooks/useSelected.tsx  |   7 +-
 .../src/hooks/useSyncServerStatus.ts          |   7 +-
 .../src/hooks/useUpdatedAccounts.ts           |   7 +
 packages/desktop-client/src/style/theme.tsx   |  16 +-
 .../loot-core/src/client/actions/account.ts   |   7 +
 .../loot-core/src/client/actions/prefs.ts     |   4 +-
 .../src/client/data-hooks/accounts.tsx        |  36 --
 .../src/client/data-hooks/payees.tsx          |  36 --
 packages/loot-core/src/client/privacy.ts      |   5 -
 .../loot-core/src/client/reducers/queries.ts  |   6 +
 .../src/client/state-types/modals.d.ts        |   2 +-
 .../src/client/state-types/queries.d.ts       |   3 +
 packages/loot-core/src/shared/categories.ts   | 106 ------
 packages/loot-core/src/types/prefs.d.ts       |   1 +
 upcoming-release-notes/2293.md                |   6 +
 104 files changed, 1045 insertions(+), 1492 deletions(-)
 create mode 100644 packages/desktop-client/src/components/sidebar/SidebarProvider.tsx
 delete mode 100644 packages/desktop-client/src/components/sidebar/SidebarWithData.tsx
 create mode 100644 packages/desktop-client/src/hooks/useAccount.ts
 create mode 100644 packages/desktop-client/src/hooks/useAccounts.ts
 create mode 100644 packages/desktop-client/src/hooks/useBudgetedAccounts.ts
 create mode 100644 packages/desktop-client/src/hooks/useClosedAccounts.ts
 create mode 100644 packages/desktop-client/src/hooks/useDateFormat.ts
 create mode 100644 packages/desktop-client/src/hooks/useFailedAccounts.ts
 create mode 100644 packages/desktop-client/src/hooks/useGlobalPref.ts
 create mode 100644 packages/desktop-client/src/hooks/useLocalPref.ts
 create mode 100644 packages/desktop-client/src/hooks/useLocalPrefs.ts
 create mode 100644 packages/desktop-client/src/hooks/useOffBudgetAccounts.ts
 create mode 100644 packages/desktop-client/src/hooks/usePayee.ts
 create mode 100644 packages/desktop-client/src/hooks/usePayees.ts
 create mode 100644 packages/desktop-client/src/hooks/usePrivacyMode.ts
 create mode 100644 packages/desktop-client/src/hooks/useUpdatedAccounts.ts
 delete mode 100644 packages/loot-core/src/client/data-hooks/accounts.tsx
 delete mode 100644 packages/loot-core/src/client/data-hooks/payees.tsx
 delete mode 100644 packages/loot-core/src/client/privacy.ts
 delete mode 100644 packages/loot-core/src/shared/categories.ts
 create mode 100644 upcoming-release-notes/2293.md

diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png
index fa4ff40ee97ecb8e257683496581ccbe298620d7..e1ed15d720db70723d09bf378709c32a6c0559ee 100644
GIT binary patch
literal 24585
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
E0Q$GZ!2kdN

literal 25638
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

diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png
index 4ac36791ac107c7087a25023cfa1651d2a316408..866d234e40ee46bb86bdb7bf2f37d07f5fec9b77 100644
GIT binary patch
literal 24829
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
XeM+Wl$a4d3kLt0Sj%u;8^_zbH{;yuG

literal 26212
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
NWkq#`GI_J$e*^BQvSa`N

diff --git a/packages/desktop-client/src/components/App.tsx b/packages/desktop-client/src/components/App.tsx
index 696c7633e..8323f7247 100644
--- a/packages/desktop-client/src/components/App.tsx
+++ b/packages/desktop-client/src/components/App.tsx
@@ -7,17 +7,15 @@ import {
 } from 'react-error-boundary';
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type AppState } from 'loot-core/client/state-types/app';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import * as Platform from 'loot-core/src/client/platform';
+import { type State } from 'loot-core/src/client/state-types';
 import {
   init as initConnection,
   send,
 } from 'loot-core/src/platform/client/fetch';
-import { type GlobalPrefs } from 'loot-core/src/types/prefs';
 
 import { useActions } from '../hooks/useActions';
+import { useLocalPref } from '../hooks/useLocalPref';
 import { installPolyfills } from '../polyfills';
 import { ResponsiveProvider } from '../ResponsiveProvider';
 import { styles, hasHiddenScrollbars, ThemeStyle } from '../style';
@@ -34,26 +32,13 @@ import { UpdateNotification } from './UpdateNotification';
 type AppInnerProps = {
   budgetId: string;
   cloudFileId: string;
-  loadingText: string;
-  loadBudget: (
-    id: string,
-    loadingText?: string,
-    options?: object,
-  ) => Promise<void>;
-  closeBudget: () => Promise<void>;
-  loadGlobalPrefs: () => Promise<GlobalPrefs>;
 };
 
-function AppInner({
-  budgetId,
-  cloudFileId,
-  loadingText,
-  loadBudget,
-  closeBudget,
-  loadGlobalPrefs,
-}: AppInnerProps) {
+function AppInner({ budgetId, cloudFileId }: AppInnerProps) {
   const [initializing, setInitializing] = useState(true);
   const { showBoundary: showErrorBoundary } = useErrorBoundary();
+  const loadingText = useSelector((state: State) => state.app.loadingText);
+  const { loadBudget, closeBudget, loadGlobalPrefs } = useActions();
 
   async function init() {
     const socketName = await global.Actual.getServerSocket();
@@ -126,16 +111,9 @@ function ErrorFallback({ error }: FallbackProps) {
 }
 
 export function App() {
-  const budgetId = useSelector<State, PrefsState['local']['id']>(
-    state => state.prefs.local && state.prefs.local.id,
-  );
-  const cloudFileId = useSelector<State, PrefsState['local']['cloudFileId']>(
-    state => state.prefs.local && state.prefs.local.cloudFileId,
-  );
-  const loadingText = useSelector<State, AppState['loadingText']>(
-    state => state.app.loadingText,
-  );
-  const { loadBudget, closeBudget, loadGlobalPrefs, sync } = useActions();
+  const [budgetId] = useLocalPref('id');
+  const [cloudFileId] = useLocalPref('cloudFileId');
+  const { sync } = useActions();
   const [hiddenScrollbars, setHiddenScrollbars] = useState(
     hasHiddenScrollbars(),
   );
@@ -184,14 +162,7 @@ export function App() {
             {process.env.REACT_APP_REVIEW_ID && !Platform.isPlaywright && (
               <DevelopmentTopBar />
             )}
-            <AppInner
-              budgetId={budgetId}
-              cloudFileId={cloudFileId}
-              loadingText={loadingText}
-              loadBudget={loadBudget}
-              closeBudget={closeBudget}
-              loadGlobalPrefs={loadGlobalPrefs}
-            />
+            <AppInner budgetId={budgetId} cloudFileId={cloudFileId} />
           </ErrorBoundary>
           <ThemeStyle />
         </View>
diff --git a/packages/desktop-client/src/components/BankSyncStatus.tsx b/packages/desktop-client/src/components/BankSyncStatus.tsx
index 3fde066fa..f49b92007 100644
--- a/packages/desktop-client/src/components/BankSyncStatus.tsx
+++ b/packages/desktop-client/src/components/BankSyncStatus.tsx
@@ -2,8 +2,7 @@ import React from 'react';
 import { useSelector } from 'react-redux';
 import { useTransition, animated } from 'react-spring';
 
-import { type State } from 'loot-core/client/state-types';
-import { type AccountState } from 'loot-core/client/state-types/account';
+import { type State } from 'loot-core/src/client/state-types';
 
 import { theme, styles } from '../style';
 
@@ -12,8 +11,8 @@ import { Text } from './common/Text';
 import { View } from './common/View';
 
 export function BankSyncStatus() {
-  const accountsSyncing = useSelector<State, AccountState['accountsSyncing']>(
-    state => state.account.accountsSyncing,
+  const accountsSyncing = useSelector(
+    (state: State) => state.account.accountsSyncing,
   );
 
   const name = accountsSyncing
diff --git a/packages/desktop-client/src/components/FinancesApp.tsx b/packages/desktop-client/src/components/FinancesApp.tsx
index 29c241a14..8024afe79 100644
--- a/packages/desktop-client/src/components/FinancesApp.tsx
+++ b/packages/desktop-client/src/components/FinancesApp.tsx
@@ -2,6 +2,7 @@
 import React, { type ReactElement, useEffect, useMemo } from 'react';
 import { DndProvider } from 'react-dnd';
 import { HTML5Backend as Backend } from 'react-dnd-html5-backend';
+import { useSelector } from 'react-redux';
 import {
   Route,
   Routes,
@@ -13,12 +14,12 @@ import {
 
 import hotkeys from 'hotkeys-js';
 
-import { AccountsProvider } from 'loot-core/src/client/data-hooks/accounts';
-import { PayeesProvider } from 'loot-core/src/client/data-hooks/payees';
 import { SpreadsheetProvider } from 'loot-core/src/client/SpreadsheetProvider';
+import { type State } from 'loot-core/src/client/state-types';
 import { checkForUpdateNotification } from 'loot-core/src/client/update-notification';
 import * as undo from 'loot-core/src/platform/client/undo';
 
+import { useAccounts } from '../hooks/useAccounts';
 import { useActions } from '../hooks/useActions';
 import { useNavigate } from '../hooks/useNavigate';
 import { useResponsive } from '../ResponsiveProvider';
@@ -39,7 +40,8 @@ import { Reports } from './reports';
 import { NarrowAlternate, WideComponent } from './responsive';
 import { ScrollProvider } from './ScrollProvider';
 import { Settings } from './settings';
-import { FloatableSidebar, SidebarProvider } from './sidebar';
+import { FloatableSidebar } from './sidebar';
+import { SidebarProvider } from './sidebar/SidebarProvider';
 import { Titlebar, TitlebarProvider } from './Titlebar';
 import { TransactionEdit } from './transactions/MobileTransaction';
 
@@ -71,18 +73,19 @@ function WideNotSupported({ children, redirectTo = '/budget' }) {
   return isNarrowWidth ? children : null;
 }
 
-function RouterBehaviors({ getAccounts }) {
+function RouterBehaviors() {
   const navigate = useNavigate();
+  const accounts = useAccounts();
+  const accountsLoaded = useSelector(
+    (state: State) => state.queries.accountsLoaded,
+  );
   useEffect(() => {
-    // Get the accounts and check if any exist. If there are no
-    // accounts, we want to redirect the user to the All Accounts
-    // screen which will prompt them to add an account
-    getAccounts().then(accounts => {
-      if (accounts.length === 0) {
-        navigate('/accounts');
-      }
-    });
-  }, []);
+    // If there are no accounts, we want to redirect the user to
+    // the All Accounts screen which will prompt them to add an account
+    if (accountsLoaded && accounts.length === 0) {
+      navigate('/accounts');
+    }
+  }, [accountsLoaded, accounts]);
 
   const location = useLocation();
   const href = useHref(location);
@@ -116,7 +119,7 @@ function FinancesAppWithoutContext() {
 
   return (
     <BrowserRouter>
-      <RouterBehaviors getAccounts={actions.getAccounts} />
+      <RouterBehaviors />
       <ExposeNavigate />
 
       <View style={{ height: '100%' }}>
@@ -265,13 +268,9 @@ export function FinancesApp() {
       <TitlebarProvider>
         <SidebarProvider>
           <BudgetMonthCountProvider>
-            <PayeesProvider>
-              <AccountsProvider>
-                <DndProvider backend={Backend}>
-                  <ScrollProvider>{app}</ScrollProvider>
-                </DndProvider>
-              </AccountsProvider>
-            </PayeesProvider>
+            <DndProvider backend={Backend}>
+              <ScrollProvider>{app}</ScrollProvider>
+            </DndProvider>
           </BudgetMonthCountProvider>
         </SidebarProvider>
       </TitlebarProvider>
diff --git a/packages/desktop-client/src/components/LoggedInUser.tsx b/packages/desktop-client/src/components/LoggedInUser.tsx
index bfd037ad4..f1043b764 100644
--- a/packages/desktop-client/src/components/LoggedInUser.tsx
+++ b/packages/desktop-client/src/components/LoggedInUser.tsx
@@ -2,8 +2,7 @@
 import React, { useState, useEffect } from 'react';
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type UserState } from 'loot-core/client/state-types/user';
+import { type State } from 'loot-core/src/client/state-types';
 
 import { useActions } from '../hooks/useActions';
 import { theme, styles, type CSSProperties } from '../style';
@@ -25,9 +24,7 @@ export function LoggedInUser({
   style,
   color,
 }: LoggedInUserProps) {
-  const userData = useSelector<State, UserState['data']>(
-    state => state.user.data,
-  );
+  const userData = useSelector((state: State) => state.user.data);
   const { getUserData, signOut, closeBudget } = useActions();
   const [loading, setLoading] = useState(true);
   const [menuOpen, setMenuOpen] = useState(false);
diff --git a/packages/desktop-client/src/components/ManageRules.tsx b/packages/desktop-client/src/components/ManageRules.tsx
index 38634a989..2459fcb44 100644
--- a/packages/desktop-client/src/components/ManageRules.tsx
+++ b/packages/desktop-client/src/components/ManageRules.tsx
@@ -7,10 +7,8 @@ import React, {
   type SetStateAction,
   type Dispatch,
 } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
+import { useDispatch } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type QueriesState } from 'loot-core/client/state-types/queries';
 import { pushModal } from 'loot-core/src/client/actions/modals';
 import { initiallyLoadPayees } from 'loot-core/src/client/actions/queries';
 import { send } from 'loot-core/src/platform/client/fetch';
@@ -19,7 +17,9 @@ import { mapField, friendlyOp } from 'loot-core/src/shared/rules';
 import { describeSchedule } from 'loot-core/src/shared/schedules';
 import { type RuleEntity } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../hooks/useAccounts';
 import { useCategories } from '../hooks/useCategories';
+import { usePayees } from '../hooks/usePayees';
 import { useSelected, SelectedProvider } from '../hooks/useSelected';
 import { theme } from '../style';
 
@@ -105,18 +105,13 @@ function ManageRulesContent({
 
   const { data: schedules } = SchedulesQuery.useQuery();
   const { list: categories } = useCategories();
-  const state = useSelector<
-    State,
-    {
-      payees: QueriesState['payees'];
-      accounts: QueriesState['accounts'];
-      schedules: ReturnType<(typeof SchedulesQuery)['useQuery']>;
-    }
-  >(state => ({
-    payees: state.queries.payees,
-    accounts: state.queries.accounts,
+  const payees = usePayees();
+  const accounts = useAccounts();
+  const state = {
+    payees,
+    accounts,
     schedules,
-  }));
+  };
   const filterData = useMemo(
     () => ({
       ...state,
diff --git a/packages/desktop-client/src/components/MobileWebMessage.tsx b/packages/desktop-client/src/components/MobileWebMessage.tsx
index bc3e0c7ac..c54da6eed 100644
--- a/packages/desktop-client/src/components/MobileWebMessage.tsx
+++ b/packages/desktop-client/src/components/MobileWebMessage.tsx
@@ -1,10 +1,6 @@
 import React, { useState } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-
-import { savePrefs } from 'loot-core/src/client/actions';
-import { type State } from 'loot-core/src/client/state-types';
-import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
 
+import { useLocalPref } from '../hooks/useLocalPref';
 import { useResponsive } from '../ResponsiveProvider';
 import { theme, styles } from '../style';
 
@@ -16,30 +12,24 @@ import { Checkbox } from './forms';
 const buttonStyle = { border: 0, fontSize: 15, padding: '10px 13px' };
 
 export function MobileWebMessage() {
-  const hideMobileMessagePref = useSelector<
-    State,
-    PrefsState['local']['hideMobileMessage']
-  >(state => {
-    return (state.prefs.local && state.prefs.local.hideMobileMessage) || true;
-  });
+  const [hideMobileMessage = true, setHideMobileMessagePref] =
+    useLocalPref('hideMobileMessage');
 
   const { isNarrowWidth } = useResponsive();
 
   const [show, setShow] = useState(
     isNarrowWidth &&
-      !hideMobileMessagePref &&
+      !hideMobileMessage &&
       !document.cookie.match(/hideMobileMessage=true/),
   );
   const [requestDontRemindMe, setRequestDontRemindMe] = useState(false);
 
-  const dispatch = useDispatch();
-
   function onTry() {
     setShow(false);
 
     if (requestDontRemindMe) {
       // remember the pref indefinitely
-      dispatch(savePrefs({ hideMobileMessage: true }));
+      setHideMobileMessagePref(true);
     } else {
       // Set a cookie for 5 minutes
       const d = new Date();
diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx
index 93ae55592..56b599861 100644
--- a/packages/desktop-client/src/components/Modals.tsx
+++ b/packages/desktop-client/src/components/Modals.tsx
@@ -4,16 +4,10 @@ import { useSelector } from 'react-redux';
 import { useLocation } from 'react-router-dom';
 
 import { type State } from 'loot-core/src/client/state-types';
-import {
-  type ModalsState,
-  type PopModalAction,
-} from 'loot-core/src/client/state-types/modals';
-import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
-import { type QueriesState } from 'loot-core/src/client/state-types/queries';
+import { type PopModalAction } from 'loot-core/src/client/state-types/modals';
 import { send } from 'loot-core/src/platform/client/fetch';
 
 import { useActions } from '../hooks/useActions';
-import { useCategories } from '../hooks/useCategories';
 import { useSyncServerStatus } from '../hooks/useSyncServerStatus';
 
 import { CategoryGroupMenu } from './modals/CategoryGroupMenu';
@@ -56,19 +50,8 @@ export type CommonModalProps = {
 };
 
 export function Modals() {
-  const modalStack = useSelector<State, ModalsState['modalStack']>(
-    state => state.modals.modalStack,
-  );
-  const isHidden = useSelector<State, ModalsState['isHidden']>(
-    state => state.modals.isHidden,
-  );
-  const accounts = useSelector<State, QueriesState['accounts']>(
-    state => state.queries.accounts,
-  );
-  const { grouped: categoryGroups, list: categories } = useCategories();
-  const budgetId = useSelector<State, PrefsState['local']['id']>(
-    state => state.prefs.local && state.prefs.local.id,
-  );
+  const modalStack = useSelector((state: State) => state.modals.modalStack);
+  const isHidden = useSelector((state: State) => state.modals.isHidden);
   const actions = useActions();
   const location = useLocation();
 
@@ -118,8 +101,6 @@ export function Modals() {
               account={options.account}
               balance={options.balance}
               canDelete={options.canDelete}
-              accounts={accounts.filter(acct => acct.closed === 0)}
-              categoryGroups={categoryGroups}
               actions={actions}
             />
           );
@@ -130,7 +111,6 @@ export function Modals() {
               modalProps={modalProps}
               externalAccounts={options.accounts}
               requisitionId={options.requisitionId}
-              localAccounts={accounts.filter(acct => acct.closed === 0)}
               actions={actions}
               syncSource={options.syncSource}
             />
@@ -140,15 +120,8 @@ export function Modals() {
           return (
             <ConfirmCategoryDelete
               modalProps={modalProps}
-              category={
-                'category' in options &&
-                categories.find(c => c.id === options.category)
-              }
-              group={
-                'group' in options &&
-                categoryGroups.find(g => g.id === options.group)
-              }
-              categoryGroups={categoryGroups}
+              category={options.category}
+              group={options.group}
               onDelete={options.onDelete}
             />
           );
@@ -166,7 +139,7 @@ export function Modals() {
           return (
             <LoadBackup
               watchUpdates
-              budgetId={budgetId}
+              budgetId={options.budgetId}
               modalProps={modalProps}
               actions={actions}
               backupDisabled={false}
diff --git a/packages/desktop-client/src/components/Notifications.tsx b/packages/desktop-client/src/components/Notifications.tsx
index ef5db09f4..290b3ae7c 100644
--- a/packages/desktop-client/src/components/Notifications.tsx
+++ b/packages/desktop-client/src/components/Notifications.tsx
@@ -7,11 +7,8 @@ import React, {
 } from 'react';
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import type {
-  NotificationWithId,
-  NotificationsState,
-} from 'loot-core/src/client/state-types/notifications';
+import { type State } from 'loot-core/src/client/state-types';
+import type { NotificationWithId } from 'loot-core/src/client/state-types/notifications';
 
 import { useActions } from '../hooks/useActions';
 import { AnimatedLoading } from '../icons/AnimatedLoading';
@@ -242,8 +239,8 @@ function Notification({
 
 export function Notifications({ style }: { style?: CSSProperties }) {
   const { removeNotification } = useActions();
-  const notifications = useSelector<State, NotificationsState['notifications']>(
-    state => state.notifications.notifications,
+  const notifications = useSelector(
+    (state: State) => state.notifications.notifications,
   );
   return (
     <View
diff --git a/packages/desktop-client/src/components/PrivacyFilter.tsx b/packages/desktop-client/src/components/PrivacyFilter.tsx
index f8596b7c8..5a455dc60 100644
--- a/packages/desktop-client/src/components/PrivacyFilter.tsx
+++ b/packages/desktop-client/src/components/PrivacyFilter.tsx
@@ -7,8 +7,7 @@ import React, {
   type ReactNode,
 } from 'react';
 
-import { usePrivacyMode } from 'loot-core/src/client/privacy';
-
+import { usePrivacyMode } from '../hooks/usePrivacyMode';
 import { useResponsive } from '../ResponsiveProvider';
 
 import { View } from './common/View';
diff --git a/packages/desktop-client/src/components/ThemeSelector.tsx b/packages/desktop-client/src/components/ThemeSelector.tsx
index e8daef9d6..415089cb1 100644
--- a/packages/desktop-client/src/components/ThemeSelector.tsx
+++ b/packages/desktop-client/src/components/ThemeSelector.tsx
@@ -2,7 +2,6 @@ import React, { useState } from 'react';
 
 import type { Theme } from 'loot-core/src/types/prefs';
 
-import { useActions } from '../hooks/useActions';
 import { SvgMoonStars, SvgSun, SvgSystem } from '../icons/v2';
 import { useResponsive } from '../ResponsiveProvider';
 import { type CSSProperties, themeOptions, useTheme } from '../style';
@@ -16,8 +15,7 @@ type ThemeSelectorProps = {
 };
 
 export function ThemeSelector({ style }: ThemeSelectorProps) {
-  const theme = useTheme();
-  const { saveGlobalPrefs } = useActions();
+  const [theme, switchTheme] = useTheme();
   const [menuOpen, setMenuOpen] = useState(false);
 
   const { isNarrowWidth } = useResponsive();
@@ -28,12 +26,9 @@ export function ThemeSelector({ style }: ThemeSelectorProps) {
     auto: SvgSystem,
   } as const;
 
-  async function onMenuSelect(newTheme: string) {
+  function onMenuSelect(newTheme: Theme) {
     setMenuOpen(false);
-
-    saveGlobalPrefs({
-      theme: newTheme as Theme,
-    });
+    switchTheme(newTheme);
   }
 
   const Icon = themeIcons[theme] || SvgSun;
diff --git a/packages/desktop-client/src/components/Titlebar.tsx b/packages/desktop-client/src/components/Titlebar.tsx
index b532412dc..8a08b283f 100644
--- a/packages/desktop-client/src/components/Titlebar.tsx
+++ b/packages/desktop-client/src/components/Titlebar.tsx
@@ -6,11 +6,8 @@ import React, {
   useContext,
   type ReactNode,
 } from 'react';
-import { useSelector } from 'react-redux';
 import { Routes, Route, useLocation } from 'react-router-dom';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import * as Platform from 'loot-core/src/client/platform';
 import * as queries from 'loot-core/src/client/queries';
 import { listen } from 'loot-core/src/platform/client/fetch';
@@ -18,6 +15,8 @@ import { type LocalPrefs } from 'loot-core/src/types/prefs';
 
 import { useActions } from '../hooks/useActions';
 import { useFeatureFlag } from '../hooks/useFeatureFlag';
+import { useGlobalPref } from '../hooks/useGlobalPref';
+import { useLocalPref } from '../hooks/useLocalPref';
 import { useNavigate } from '../hooks/useNavigate';
 import { SvgArrowLeft } from '../icons/v1';
 import {
@@ -41,7 +40,7 @@ import { View } from './common/View';
 import { KeyHandlers } from './KeyHandlers';
 import { LoggedInUser } from './LoggedInUser';
 import { useServerURL } from './ServerContext';
-import { useSidebar } from './sidebar';
+import { useSidebar } from './sidebar/SidebarProvider';
 import { useSheetValue } from './spreadsheet/useSheetValue';
 import { ThemeSelector } from './ThemeSelector';
 import { Tooltip } from './tooltips';
@@ -120,11 +119,8 @@ type PrivacyButtonProps = {
 };
 
 function PrivacyButton({ style }: PrivacyButtonProps) {
-  const isPrivacyEnabled = useSelector<
-    State,
-    PrefsState['local']['isPrivacyEnabled']
-  >(state => state.prefs.local?.isPrivacyEnabled);
-  const { savePrefs } = useActions();
+  const [isPrivacyEnabled, setPrivacyEnabledPref] =
+    useLocalPref('isPrivacyEnabled');
 
   const privacyIconStyle = { width: 15, height: 15 };
 
@@ -132,7 +128,7 @@ function PrivacyButton({ style }: PrivacyButtonProps) {
     <Button
       type="bare"
       aria-label={`${isPrivacyEnabled ? 'Disable' : 'Enable'} privacy mode`}
-      onClick={() => savePrefs({ isPrivacyEnabled: !isPrivacyEnabled })}
+      onClick={() => setPrivacyEnabledPref(!isPrivacyEnabled)}
       style={style}
     >
       {isPrivacyEnabled ? (
@@ -149,9 +145,7 @@ type SyncButtonProps = {
   isMobile?: boolean;
 };
 function SyncButton({ style, isMobile = false }: SyncButtonProps) {
-  const cloudFileId = useSelector<State, PrefsState['local']['cloudFileId']>(
-    state => state.prefs.local?.cloudFileId,
-  );
+  const [cloudFileId] = useLocalPref('cloudFileId');
   const { sync } = useActions();
 
   const [syncing, setSyncing] = useState(false);
@@ -291,13 +285,8 @@ function SyncButton({ style, isMobile = false }: SyncButtonProps) {
 }
 
 function BudgetTitlebar() {
-  const maxMonths = useSelector<State, PrefsState['global']['maxMonths']>(
-    state => state.prefs.global?.maxMonths,
-  );
-  const budgetType = useSelector<State, PrefsState['local']['budgetType']>(
-    state => state.prefs.local?.budgetType,
-  );
-  const { saveGlobalPrefs } = useActions();
+  const [maxMonths, setMaxMonthsPref] = useGlobalPref('maxMonths');
+  const [budgetType] = useLocalPref('budgetType');
   const { sendEvent } = useContext(TitlebarContext);
 
   const [loading, setLoading] = useState(false);
@@ -326,7 +315,7 @@ function BudgetTitlebar() {
     <View style={{ flexDirection: 'row', alignItems: 'center' }}>
       <MonthCountSelector
         maxMonths={maxMonths || 1}
-        onChange={value => saveGlobalPrefs({ maxMonths: value })}
+        onChange={value => setMaxMonthsPref(value)}
       />
       {reportBudgetEnabled && (
         <View style={{ marginLeft: -5 }}>
@@ -399,10 +388,7 @@ export function Titlebar({ style }: TitlebarProps) {
   const sidebar = useSidebar();
   const { isNarrowWidth } = useResponsive();
   const serverURL = useServerURL();
-  const floatingSidebar = useSelector<
-    State,
-    PrefsState['global']['floatingSidebar']
-  >(state => state.prefs.global?.floatingSidebar);
+  const [floatingSidebar] = useGlobalPref('floatingSidebar');
 
   return isNarrowWidth ? null : (
     <View
diff --git a/packages/desktop-client/src/components/UpdateNotification.tsx b/packages/desktop-client/src/components/UpdateNotification.tsx
index 18c992466..f70525028 100644
--- a/packages/desktop-client/src/components/UpdateNotification.tsx
+++ b/packages/desktop-client/src/components/UpdateNotification.tsx
@@ -1,8 +1,7 @@
 import React from 'react';
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type AppState } from 'loot-core/client/state-types/app';
+import { type State } from 'loot-core/src/client/state-types';
 
 import { useActions } from '../hooks/useActions';
 import { SvgClose } from '../icons/v1';
@@ -14,13 +13,10 @@ import { Text } from './common/Text';
 import { View } from './common/View';
 
 export function UpdateNotification() {
-  const updateInfo = useSelector<State, AppState['updateInfo']>(
-    state => state.app.updateInfo,
+  const updateInfo = useSelector((state: State) => state.app.updateInfo);
+  const showUpdateNotification = useSelector(
+    (state: State) => state.app.showUpdateNotification,
   );
-  const showUpdateNotification = useSelector<
-    State,
-    AppState['showUpdateNotification']
-  >(state => state.app.showUpdateNotification);
 
   const { updateApp, setAppState } = useActions();
 
diff --git a/packages/desktop-client/src/components/accounts/Account.jsx b/packages/desktop-client/src/components/accounts/Account.jsx
index 1fb7e32a1..48f30a99a 100644
--- a/packages/desktop-client/src/components/accounts/Account.jsx
+++ b/packages/desktop-client/src/components/accounts/Account.jsx
@@ -26,7 +26,12 @@ import {
 } from 'loot-core/src/shared/transactions';
 import { applyChanges, groupById } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { useFailedAccounts } from '../../hooks/useFailedAccounts';
+import { useLocalPref } from '../../hooks/useLocalPref';
+import { usePayees } from '../../hooks/usePayees';
 import { SelectedProviderWithItems } from '../../hooks/useSelected';
 import { styles, theme } from '../../style';
 import { Button } from '../common/Button';
@@ -1532,23 +1537,41 @@ export function Account() {
   const location = useLocation();
 
   const { grouped: categoryGroups } = useCategories();
-  const state = useSelector(state => ({
-    newTransactions: state.queries.newTransactions,
-    matchedTransactions: state.queries.matchedTransactions,
-    accounts: state.queries.accounts,
-    failedAccounts: state.account.failedAccounts,
-    dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy',
-    hideFraction: state.prefs.local.hideFraction || false,
-    expandSplits: state.prefs.local['expand-splits'],
-    showBalances: params.id && state.prefs.local['show-balances-' + params.id],
-    showCleared: params.id && !state.prefs.local['hide-cleared-' + params.id],
-    showExtraBalances:
-      state.prefs.local['show-extra-balances-' + params.id || 'all-accounts'],
-    payees: state.queries.payees,
-    modalShowing: state.modals.modalStack.length > 0,
-    accountsSyncing: state.account.accountsSyncing,
-    lastUndoState: state.app.lastUndoState,
-  }));
+  const newTransactions = useSelector(state => state.queries.newTransactions);
+  const matchedTransactions = useSelector(
+    state => state.queries.matchedTransactions,
+  );
+  const accounts = useAccounts();
+  const payees = usePayees();
+  const failedAccounts = useFailedAccounts();
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+  const [hideFraction = false] = useLocalPref('hideFraction');
+  const [expandSplits] = useLocalPref('expand-splits');
+  const [showBalances] = useLocalPref(`show-balances-${params.id}`);
+  const [hideCleared] = useLocalPref(`hide-cleared-${params.id}`);
+  const [showExtraBalances] = useLocalPref(
+    `show-extra-balances-${params.id || 'all-accounts'}`,
+  );
+  const modalShowing = useSelector(state => state.modals.modalStack.length > 0);
+  const accountsSyncing = useSelector(state => state.account.accountsSyncing);
+  const lastUndoState = useSelector(state => state.app.lastUndoState);
+
+  const state = {
+    newTransactions,
+    matchedTransactions,
+    accounts,
+    failedAccounts,
+    dateFormat,
+    hideFraction,
+    expandSplits,
+    showBalances,
+    showCleared: !hideCleared,
+    showExtraBalances,
+    payees,
+    modalShowing,
+    accountsSyncing,
+    lastUndoState,
+  };
 
   const dispatch = useDispatch();
   const filtersList = useFilters();
diff --git a/packages/desktop-client/src/components/accounts/AccountSyncCheck.jsx b/packages/desktop-client/src/components/accounts/AccountSyncCheck.jsx
index 423c99b7c..09180381d 100644
--- a/packages/desktop-client/src/components/accounts/AccountSyncCheck.jsx
+++ b/packages/desktop-client/src/components/accounts/AccountSyncCheck.jsx
@@ -3,6 +3,7 @@ import { useSelector } from 'react-redux';
 import { useParams } from 'react-router-dom';
 
 import { authorizeBank } from '../../gocardless';
+import { useAccounts } from '../../hooks/useAccounts';
 import { useActions } from '../../hooks/useActions';
 import { SvgExclamationOutline } from '../../icons/v1';
 import { theme } from '../../style';
@@ -49,7 +50,7 @@ function getErrorMessage(type, code) {
 }
 
 export function AccountSyncCheck() {
-  const accounts = useSelector(state => state.queries.accounts);
+  const accounts = useAccounts();
   const failedAccounts = useSelector(state => state.account.failedAccounts);
   const { unlinkAccount, pushModal } = useActions();
 
diff --git a/packages/desktop-client/src/components/accounts/Header.jsx b/packages/desktop-client/src/components/accounts/Header.jsx
index 4e181a514..80c1030ca 100644
--- a/packages/desktop-client/src/components/accounts/Header.jsx
+++ b/packages/desktop-client/src/components/accounts/Header.jsx
@@ -1,5 +1,6 @@
 import React, { useState, useRef } from 'react';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { useSyncServerStatus } from '../../hooks/useSyncServerStatus';
 import { AnimatedLoading } from '../../icons/AnimatedLoading';
 import { SvgAdd } from '../../icons/v1';
@@ -53,7 +54,6 @@ export function AccountHeader({
   search,
   filters,
   conditionsOp,
-  savePrefs,
   pushModal,
   onSearch,
   onAddTransaction,
@@ -86,6 +86,7 @@ export function AccountHeader({
   const syncServerStatus = useSyncServerStatus();
   const isUsingServer = syncServerStatus !== 'no-server';
   const isServerOffline = syncServerStatus === 'offline';
+  const [_, setExpandSplitsPref] = useLocalPref('expand-splits');
 
   let canSync = account && account.account_id && isUsingServer;
   if (!account) {
@@ -100,9 +101,7 @@ export function AccountHeader({
         id: tableRef.current.getScrolledItem(),
       });
 
-      savePrefs({
-        'expand-splits': !(splitsExpanded.state.mode === 'expand'),
-      });
+      setExpandSplitsPref(!(splitsExpanded.state.mode === 'expand'));
     }
   }
 
diff --git a/packages/desktop-client/src/components/accounts/MobileAccount.jsx b/packages/desktop-client/src/components/accounts/MobileAccount.jsx
index b8d4bb6ce..0b06e280e 100644
--- a/packages/desktop-client/src/components/accounts/MobileAccount.jsx
+++ b/packages/desktop-client/src/components/accounts/MobileAccount.jsx
@@ -19,8 +19,13 @@ import {
   ungroupTransactions,
 } from 'loot-core/src/shared/transactions';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { useLocalPref } from '../../hooks/useLocalPref';
+import { useLocalPrefs } from '../../hooks/useLocalPrefs';
 import { useNavigate } from '../../hooks/useNavigate';
+import { usePayees } from '../../hooks/usePayees';
 import { useSetThemeColor } from '../../hooks/useSetThemeColor';
 import { theme, styles } from '../../style';
 import { Button } from '../common/Button';
@@ -72,19 +77,27 @@ function PreviewTransactions({ children }) {
 let paged;
 
 export function Account(props) {
-  const accounts = useSelector(state => state.queries.accounts);
+  const accounts = useAccounts();
+  const payees = usePayees();
 
   const navigate = useNavigate();
   const [transactions, setTransactions] = useState([]);
   const [searchText, setSearchText] = useState('');
   const [currentQuery, setCurrentQuery] = useState();
 
-  const state = useSelector(state => ({
-    payees: state.queries.payees,
-    newTransactions: state.queries.newTransactions,
-    prefs: state.prefs.local,
-    dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  }));
+  const newTransactions = useSelector(state => state.queries.newTransactions);
+  const prefs = useLocalPrefs();
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+  const [_numberFormat] = useLocalPref('numberFormat');
+  const numberFormat = _numberFormat || 'comma-dot';
+  const [hideFraction = false] = useLocalPref('hideFraction');
+
+  const state = {
+    payees,
+    newTransactions,
+    prefs,
+    dateFormat,
+  };
 
   const dispatch = useDispatch();
   const actionCreators = useMemo(
@@ -134,11 +147,6 @@ export function Account(props) {
         }
       });
 
-      if (accounts.length === 0) {
-        await actionCreators.getAccounts();
-      }
-
-      await actionCreators.initiallyLoadPayees();
       await fetchTransactions();
 
       actionCreators.markAccountRead(accountId);
@@ -216,8 +224,6 @@ export function Account(props) {
   const balance = queries.accountBalance(account);
   const balanceCleared = queries.accountBalanceCleared(account);
   const balanceUncleared = queries.accountBalanceUncleared(account);
-  const numberFormat = state.prefs.numberFormat || 'comma-dot';
-  const hideFraction = state.prefs.hideFraction || false;
 
   return (
     <SchedulesProvider
diff --git a/packages/desktop-client/src/components/accounts/MobileAccounts.jsx b/packages/desktop-client/src/components/accounts/MobileAccounts.jsx
index 4087fdbe0..f05662950 100644
--- a/packages/desktop-client/src/components/accounts/MobileAccounts.jsx
+++ b/packages/desktop-client/src/components/accounts/MobileAccounts.jsx
@@ -1,10 +1,12 @@
-import React, { useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
+import React, { useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
 
+import { replaceModal, syncAndDownload } from 'loot-core/src/client/actions';
 import * as queries from 'loot-core/src/client/queries';
 
-import { useActions } from '../../hooks/useActions';
+import { useAccounts } from '../../hooks/useAccounts';
 import { useCategories } from '../../hooks/useCategories';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { useNavigate } from '../../hooks/useNavigate';
 import { useSetThemeColor } from '../../hooks/useSetThemeColor';
 import { SvgAdd } from '../../icons/v1';
@@ -221,26 +223,19 @@ function AccountList({
 }
 
 export function Accounts() {
-  const accounts = useSelector(state => state.queries.accounts);
+  const dispatch = useDispatch();
+  const accounts = useAccounts();
   const newTransactions = useSelector(state => state.queries.newTransactions);
   const updatedAccounts = useSelector(state => state.queries.updatedAccounts);
-  const numberFormat = useSelector(
-    state => state.prefs.local.numberFormat || 'comma-dot',
-  );
-  const hideFraction = useSelector(
-    state => state.prefs.local.hideFraction || false,
-  );
+  const [_numberFormat] = useLocalPref('numberFormat');
+  const numberFormat = _numberFormat || 'comma-dot';
+  const [hideFraction = false] = useLocalPref('hideFraction');
 
   const { list: categories } = useCategories();
-  const { getAccounts, replaceModal, syncAndDownload } = useActions();
 
   const transactions = useState({});
   const navigate = useNavigate();
 
-  useEffect(() => {
-    (async () => getAccounts())();
-  }, []);
-
   const onSelectAccount = id => {
     navigate(`/accounts/${id}`);
   };
@@ -249,6 +244,14 @@ export function Accounts() {
     navigate(`/transaction/${transaction}`);
   };
 
+  const onAddAccount = () => {
+    dispatch(replaceModal('add-account'));
+  };
+
+  const onSync = () => {
+    dispatch(syncAndDownload());
+  };
+
   useSetThemeColor(theme.mobileViewTheme);
 
   return (
@@ -265,10 +268,10 @@ export function Accounts() {
         getBalanceQuery={queries.accountBalance}
         getOnBudgetBalance={queries.budgetedAccountBalance}
         getOffBudgetBalance={queries.offbudgetAccountBalance}
-        onAddAccount={() => replaceModal('add-account')}
+        onAddAccount={onAddAccount}
         onSelectAccount={onSelectAccount}
         onSelectTransaction={onSelectTransaction}
-        onSync={syncAndDownload}
+        onSync={onSync}
       />
     </View>
   );
diff --git a/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx
index f296e7b29..778480a7d 100644
--- a/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx
+++ b/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx
@@ -3,9 +3,9 @@ import React, { Fragment, type ComponentProps, type ReactNode } from 'react';
 
 import { css } from 'glamor';
 
-import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts';
 import { type AccountEntity } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useResponsive } from '../../ResponsiveProvider';
 import { type CSSProperties, theme } from '../../style';
 import { View } from '../common/View';
@@ -86,7 +86,7 @@ export function AccountAutocomplete({
   closeOnBlur,
   ...props
 }: AccountAutoCompleteProps) {
-  let accounts = useCachedAccounts() || [];
+  let accounts = useAccounts() || [];
 
   //remove closed accounts if needed
   //then sort by closed, then offbudget
diff --git a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx
index b99009b32..84ee34bfd 100644
--- a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx
+++ b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx
@@ -13,14 +13,14 @@ import { useDispatch } from 'react-redux';
 import { css } from 'glamor';
 
 import { createPayee } from 'loot-core/src/client/actions/queries';
-import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts';
-import { useCachedPayees } from 'loot-core/src/client/data-hooks/payees';
 import { getActivePayees } from 'loot-core/src/client/reducers/queries';
 import {
   type AccountEntity,
   type PayeeEntity,
 } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../../hooks/useAccounts';
+import { usePayees } from '../../hooks/usePayees';
 import { SvgAdd } from '../../icons/v1';
 import { useResponsive } from '../../ResponsiveProvider';
 import { type CSSProperties, theme } from '../../style';
@@ -187,12 +187,12 @@ export function PayeeAutocomplete({
   payees,
   ...props
 }: PayeeAutocompleteProps) {
-  const cachedPayees = useCachedPayees();
+  const retrievedPayees = usePayees();
   if (!payees) {
-    payees = cachedPayees;
+    payees = retrievedPayees;
   }
 
-  const cachedAccounts = useCachedAccounts();
+  const cachedAccounts = useAccounts();
   if (!accounts) {
     accounts = cachedAccounts;
   }
diff --git a/packages/desktop-client/src/components/budget/BudgetCategories.jsx b/packages/desktop-client/src/components/budget/BudgetCategories.jsx
index c80bfb2ab..51183003f 100644
--- a/packages/desktop-client/src/components/budget/BudgetCategories.jsx
+++ b/packages/desktop-client/src/components/budget/BudgetCategories.jsx
@@ -1,5 +1,6 @@
 import React, { memo, useState, useMemo } from 'react';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { theme, styles } from '../../style';
 import { View } from '../common/View';
 import { DropHighlightPosContext } from '../sort';
@@ -17,12 +18,7 @@ import { separateGroups } from './util';
 export const BudgetCategories = memo(
   ({
     categoryGroups,
-    newCategoryForGroup,
-    showHiddenCategories,
-    isAddingGroup,
     editingCell,
-    collapsed,
-    setCollapsed,
     dataComponents,
     onBudgetAction,
     onShowActivity,
@@ -34,11 +30,16 @@ export const BudgetCategories = memo(
     onDeleteGroup,
     onReorderCategory,
     onReorderGroup,
-    onShowNewCategory,
-    onHideNewCategory,
-    onShowNewGroup,
-    onHideNewGroup,
   }) => {
+    const [_collapsed, setCollapsedPref] = useLocalPref('budget.collapsed');
+    const collapsed = _collapsed || [];
+    const [showHiddenCategories] = useLocalPref('budget.showHiddenCategories');
+    function onCollapse(value) {
+      setCollapsedPref(value);
+    }
+
+    const [isAddingGroup, setIsAddingGroup] = useState(false);
+    const [newCategoryForGroup, setNewCategoryForGroup] = useState(null);
     const items = useMemo(() => {
       const [expenseGroups, incomeGroup] = separateGroups(categoryGroups);
 
@@ -133,15 +134,46 @@ export const BudgetCategories = memo(
         });
       } else if (state === 'end') {
         setDragState(null);
-        setCollapsed(savedCollapsed || []);
+        onCollapse(savedCollapsed || []);
       }
     }
 
     function onToggleCollapse(id) {
       if (collapsed.includes(id)) {
-        setCollapsed(collapsed.filter(id_ => id_ !== id));
+        onCollapse(collapsed.filter(id_ => id_ !== id));
       } else {
-        setCollapsed([...collapsed, id]);
+        onCollapse([...collapsed, id]);
+      }
+    }
+
+    function onShowNewGroup() {
+      setIsAddingGroup(true);
+    }
+
+    function onHideNewGroup() {
+      setIsAddingGroup(false);
+    }
+
+    function _onSaveGroup(group) {
+      onSaveGroup?.(group);
+      if (group.id === 'new') {
+        onHideNewGroup();
+      }
+    }
+
+    function onShowNewCategory(groupId) {
+      onCollapse(collapsed.filter(c => c !== groupId));
+      setNewCategoryForGroup(groupId);
+    }
+
+    function onHideNewCategory() {
+      setNewCategoryForGroup(null);
+    }
+
+    function _onSaveCategory(category) {
+      onSaveCategory?.(category);
+      if (category.id === 'new') {
+        onHideNewCategory();
       }
     }
 
@@ -167,7 +199,7 @@ export const BudgetCategories = memo(
                   <SidebarGroup
                     group={{ id: 'new', name: '' }}
                     editing={true}
-                    onSave={onSaveGroup}
+                    onSave={_onSaveGroup}
                     onHideNewGroup={onHideNewGroup}
                     onEdit={onEditName}
                   />
@@ -187,7 +219,7 @@ export const BudgetCategories = memo(
                       id: 'new',
                     }}
                     editing={true}
-                    onSave={onSaveCategory}
+                    onSave={_onSaveCategory}
                     onHideNewCategory={onHideNewCategory}
                     onEditName={onEditName}
                   />
@@ -204,7 +236,7 @@ export const BudgetCategories = memo(
                   MonthComponent={dataComponents.ExpenseGroupComponent}
                   dragState={dragState}
                   onEditName={onEditName}
-                  onSave={onSaveGroup}
+                  onSave={_onSaveGroup}
                   onDelete={onDeleteGroup}
                   onDragChange={onDragChange}
                   onReorderGroup={onReorderGroup}
@@ -223,7 +255,7 @@ export const BudgetCategories = memo(
                   dragState={dragState}
                   onEditName={onEditName}
                   onEditMonth={onEditMonth}
-                  onSave={onSaveCategory}
+                  onSave={_onSaveCategory}
                   onDelete={onDeleteCategory}
                   onDragChange={onDragChange}
                   onReorder={onReorderCategory}
@@ -255,7 +287,7 @@ export const BudgetCategories = memo(
                   MonthComponent={dataComponents.IncomeGroupComponent}
                   collapsed={collapsed.includes(item.value.id)}
                   onEditName={onEditName}
-                  onSave={onSaveGroup}
+                  onSave={_onSaveGroup}
                   onToggleCollapse={onToggleCollapse}
                   onShowNewCategory={onShowNewCategory}
                 />
@@ -270,7 +302,7 @@ export const BudgetCategories = memo(
                   MonthComponent={dataComponents.IncomeCategoryComponent}
                   onEditName={onEditName}
                   onEditMonth={onEditMonth}
-                  onSave={onSaveCategory}
+                  onSave={_onSaveCategory}
                   onDelete={onDeleteCategory}
                   onDragChange={onDragChange}
                   onReorder={onReorderCategory}
diff --git a/packages/desktop-client/src/components/budget/BudgetTable.jsx b/packages/desktop-client/src/components/budget/BudgetTable.jsx
index 3000ebb1a..d9f4d4df8 100644
--- a/packages/desktop-client/src/components/budget/BudgetTable.jsx
+++ b/packages/desktop-client/src/components/budget/BudgetTable.jsx
@@ -1,5 +1,7 @@
 import React, { createRef, Component } from 'react';
+import { connect } from 'react-redux';
 
+import { savePrefs } from 'loot-core/src/client/actions';
 import * as monthUtils from 'loot-core/src/shared/months';
 
 import { theme, styles } from '../../style';
@@ -12,7 +14,7 @@ import { BudgetTotals } from './BudgetTotals';
 import { MonthsProvider } from './MonthsContext';
 import { findSortDown, findSortUp, getScrollbarWidth } from './util';
 
-export class BudgetTable extends Component {
+class BudgetTableInner extends Component {
   constructor(props) {
     super(props);
     this.budgetCategoriesRef = createRef();
@@ -20,7 +22,6 @@ export class BudgetTable extends Component {
     this.state = {
       editing: null,
       draggingState: null,
-      showHiddenCategories: props.prefs['budget.showHiddenCategories'] ?? false,
     };
   }
 
@@ -137,26 +138,22 @@ export class BudgetTable extends Component {
     return monthUtils.addMonths(this.props.startMonth, monthIndex);
   };
 
+  // This is called via ref.
   clearEditing() {
     this.setState({ editing: null });
   }
 
   toggleHiddenCategories = () => {
-    this.setState(prevState => ({
-      showHiddenCategories: !prevState.showHiddenCategories,
-    }));
-    this.props.savePrefs({
-      'budget.showHiddenCategories': !this.state.showHiddenCategories,
-    });
+    this.props.onToggleHiddenCategories();
   };
 
   expandAllCategories = () => {
-    this.props.setCollapsed([]);
+    this.props.onCollapse([]);
   };
 
   collapseAllCategories = () => {
-    const { setCollapsed, categoryGroups } = this.props;
-    setCollapsed(categoryGroups.map(g => g.id));
+    const { onCollapse, categoryGroups } = this.props;
+    onCollapse(categoryGroups.map(g => g.id));
   };
 
   render() {
@@ -167,21 +164,13 @@ export class BudgetTable extends Component {
       startMonth,
       numMonths,
       monthBounds,
-      collapsed,
-      setCollapsed,
-      newCategoryForGroup,
       dataComponents,
-      isAddingGroup,
       onSaveCategory,
       onSaveGroup,
       onDeleteCategory,
       onDeleteGroup,
-      onShowNewCategory,
-      onHideNewCategory,
-      onShowNewGroup,
-      onHideNewGroup,
     } = this.props;
-    const { editing, draggingState, showHiddenCategories } = this.state;
+    const { editing, draggingState } = this.state;
 
     return (
       <View
@@ -254,13 +243,8 @@ export class BudgetTable extends Component {
                 innerRef={el => (this.budgetDataNode = el)}
               >
                 <BudgetCategories
-                  showHiddenCategories={showHiddenCategories}
                   categoryGroups={categoryGroups}
-                  newCategoryForGroup={newCategoryForGroup}
-                  isAddingGroup={isAddingGroup}
                   editingCell={editing}
-                  collapsed={collapsed}
-                  setCollapsed={setCollapsed}
                   dataComponents={dataComponents}
                   onEditMonth={this.onEditMonth}
                   onEditName={this.onEditName}
@@ -270,10 +254,6 @@ export class BudgetTable extends Component {
                   onDeleteGroup={onDeleteGroup}
                   onReorderCategory={this.onReorderCategory}
                   onReorderGroup={this.onReorderGroup}
-                  onShowNewCategory={onShowNewCategory}
-                  onHideNewCategory={onHideNewCategory}
-                  onShowNewGroup={onShowNewGroup}
-                  onHideNewGroup={onHideNewGroup}
                   onBudgetAction={this.onBudgetAction}
                   onShowActivity={this.onShowActivity}
                 />
@@ -285,3 +265,35 @@ export class BudgetTable extends Component {
     );
   }
 }
+
+const mapStateToProps = state => {
+  const { grouped: categoryGroups } = state.queries.categories;
+  return {
+    categoryGroups,
+  };
+};
+
+const mapDispatchToProps = dispatch => {
+  const onCollapse = collapsedIds => {
+    dispatch(savePrefs({ 'budget.collapsed': collapsedIds }));
+  };
+
+  const onToggleHiddenCategories = () =>
+    dispatch((innerDispatch, getState) => {
+      const { prefs } = getState();
+      const showHiddenCategories = prefs.local['budget.showHiddenCategories'];
+      innerDispatch(
+        savePrefs({
+          'budget.showHiddenCategories': !showHiddenCategories,
+        }),
+      );
+    });
+  return {
+    onCollapse,
+    onToggleHiddenCategories,
+  };
+};
+
+export const BudgetTable = connect(mapStateToProps, mapDispatchToProps, null, {
+  forwardRef: true,
+})(BudgetTableInner);
diff --git a/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx b/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx
index 7a01439ab..ab366f3a6 100644
--- a/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx
+++ b/packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx
@@ -1,11 +1,7 @@
 // @ts-strict-ignore
 import React, { forwardRef, useEffect, type ComponentProps } from 'react';
-import { useSelector } from 'react-redux';
 import AutoSizer from 'react-virtualized-auto-sizer';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-
 import { useActions } from '../../hooks/useActions';
 import { View } from '../common/View';
 
@@ -37,14 +33,13 @@ type DynamicBudgetTableInnerProps = {
 } & ComponentProps<typeof BudgetTable>;
 
 const DynamicBudgetTableInner = forwardRef<
-  BudgetTable,
+  typeof BudgetTable,
   DynamicBudgetTableInnerProps
 >(
   (
     {
       width,
       height,
-      categoryGroups,
       prewarmStartMonth,
       startMonth,
       maxMonths = 3,
@@ -55,9 +50,6 @@ const DynamicBudgetTableInner = forwardRef<
     },
     ref,
   ) => {
-    const prefs = useSelector<State, PrefsState['local']>(
-      state => state.prefs.local,
-    );
     const { setDisplayMax } = useBudgetMonthCount();
     const actions = useActions();
 
@@ -91,12 +83,10 @@ const DynamicBudgetTableInner = forwardRef<
           />
           <BudgetTable
             ref={ref}
-            categoryGroups={categoryGroups}
             prewarmStartMonth={prewarmStartMonth}
             startMonth={startMonth}
             numMonths={numMonths}
             monthBounds={monthBounds}
-            prefs={prefs}
             {...actions}
             {...props}
           />
@@ -107,7 +97,7 @@ const DynamicBudgetTableInner = forwardRef<
 );
 
 export const DynamicBudgetTable = forwardRef<
-  BudgetTable,
+  typeof BudgetTable,
   DynamicBudgetTableInnerProps
 >((props, ref) => {
   return (
diff --git a/packages/desktop-client/src/components/budget/MobileBudget.tsx b/packages/desktop-client/src/components/budget/MobileBudget.tsx
index 4b98fc5f6..f5145aeec 100644
--- a/packages/desktop-client/src/components/budget/MobileBudget.tsx
+++ b/packages/desktop-client/src/components/budget/MobileBudget.tsx
@@ -1,10 +1,7 @@
 // @ts-strict-ignore
 import React, { useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
 import { useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider';
-import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
 import { send, listen } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import {
@@ -14,6 +11,7 @@ import {
 
 import { type BoundActions, useActions } from '../../hooks/useActions';
 import { useCategories } from '../../hooks/useCategories';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { useSetThemeColor } from '../../hooks/useSetThemeColor';
 import { AnimatedLoading } from '../../icons/AnimatedLoading';
 import { theme } from '../../style';
@@ -26,7 +24,6 @@ import { prewarmMonth, switchBudgetType } from './util';
 type BudgetInnerProps = {
   categories: CategoryEntity[];
   categoryGroups: CategoryGroupEntity[];
-  prefs: PrefsState['local'];
   loadPrefs: BoundActions['loadPrefs'];
   savePrefs: BoundActions['savePrefs'];
   budgetType: 'rollover' | 'report';
@@ -50,9 +47,7 @@ function BudgetInner(props: BudgetInnerProps) {
   const {
     categoryGroups,
     categories,
-    prefs,
     loadPrefs,
-    savePrefs,
     budgetType,
     spreadsheet,
     applyBudgetAction,
@@ -75,6 +70,10 @@ function BudgetInner(props: BudgetInnerProps) {
   const [initialized, setInitialized] = useState(false);
   const [editMode, setEditMode] = useState(false);
 
+  const [_numberFormat] = useLocalPref('numberFormat');
+  const numberFormat = _numberFormat || 'comma-dot';
+  const [hideFraction = false] = useLocalPref('hideFraction');
+
   useEffect(() => {
     async function init() {
       const { start, end } = await send('get-budget-bounds');
@@ -356,9 +355,6 @@ function BudgetInner(props: BudgetInnerProps) {
     });
   };
 
-  const numberFormat = prefs?.numberFormat || 'comma-dot';
-  const hideFraction = prefs?.hideFraction || false;
-
   if (!categoryGroups || !initialized) {
     return (
       <View
@@ -385,7 +381,7 @@ function BudgetInner(props: BudgetInnerProps) {
         <BudgetTable
           // This key forces the whole table rerender when the number
           // format changes
-          key={numberFormat + hideFraction}
+          key={`${numberFormat}${hideFraction}`}
           categoryGroups={categoryGroups}
           type={budgetType}
           month={currentMonth}
@@ -407,7 +403,6 @@ function BudgetInner(props: BudgetInnerProps) {
           onBudgetAction={applyBudgetAction}
           onRefresh={onRefresh}
           onSwitchBudgetType={onSwitchBudgetType}
-          savePrefs={savePrefs}
           pushModal={pushModal}
           onEditGroup={onEditGroup}
           onEditCategory={onEditCategory}
@@ -419,12 +414,8 @@ function BudgetInner(props: BudgetInnerProps) {
 
 export function Budget() {
   const { list: categories, grouped: categoryGroups } = useCategories();
-  const budgetType = useSelector<State, PrefsState['local']['budgetType']>(
-    state => state.prefs.local?.budgetType || 'rollover',
-  );
-  const prefs = useSelector<State, PrefsState['local']>(
-    state => state.prefs.local,
-  );
+  const [_budgetType] = useLocalPref('budgetType');
+  const budgetType = _budgetType || 'rollover';
 
   const actions = useActions();
   const spreadsheet = useSpreadsheet();
@@ -434,7 +425,6 @@ export function Budget() {
       categoryGroups={categoryGroups}
       categories={categories}
       budgetType={budgetType}
-      prefs={prefs}
       {...actions}
       spreadsheet={spreadsheet}
     />
diff --git a/packages/desktop-client/src/components/budget/MobileBudgetTable.jsx b/packages/desktop-client/src/components/budget/MobileBudgetTable.jsx
index a7214cf12..9a03bb71c 100644
--- a/packages/desktop-client/src/components/budget/MobileBudgetTable.jsx
+++ b/packages/desktop-client/src/components/budget/MobileBudgetTable.jsx
@@ -1,5 +1,4 @@
 import React, { memo, useRef, useState } from 'react';
-import { useSelector } from 'react-redux';
 
 import memoizeOne from 'memoize-one';
 
@@ -7,6 +6,7 @@ import { rolloverBudget, reportBudget } from 'loot-core/src/client/queries';
 import * as monthUtils from 'loot-core/src/shared/months';
 
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import {
   SingleActiveEditFormProvider,
   useSingleActiveEditForm,
@@ -1133,7 +1133,6 @@ export function BudgetTable({
   onBudgetAction,
   onRefresh,
   onSwitchBudgetType,
-  savePrefs,
   pushModal,
   onEditGroup,
   onEditCategory,
@@ -1144,24 +1143,15 @@ export function BudgetTable({
   // let editMode = false; // neuter editMode -- sorry, not rewriting drag-n-drop right now
   const format = useFormat();
 
-  const mobileShowBudgetedColPref = useSelector(state => {
-    return state.prefs?.local?.toggleMobileDisplayPref || true;
-  });
-
-  const showHiddenCategories = useSelector(state => {
-    return state.prefs?.local?.['budget.showHiddenCategories'] || false;
-  });
-
-  const [showBudgetedCol, setShowBudgetedCol] = useState(
-    !mobileShowBudgetedColPref &&
-      !document.cookie.match(/mobileShowBudgetedColPref=true/),
+  const [showSpentColumn = false, setShowSpentColumnPref] = useLocalPref(
+    'mobile.showSpentColumn',
   );
 
+  const [showHiddenCategories = false, setShowHiddenCategoriesPref] =
+    useLocalPref('budget.showHiddenCategories');
+
   function toggleDisplay() {
-    setShowBudgetedCol(!showBudgetedCol);
-    if (!showBudgetedCol) {
-      savePrefs({ mobileShowBudgetedColPref: true });
-    }
+    setShowSpentColumnPref(!showSpentColumn);
   }
 
   const buttonStyle = {
@@ -1177,9 +1167,7 @@ export function BudgetTable({
   };
 
   const onToggleHiddenCategories = () => {
-    savePrefs({
-      'budget.showHiddenCategories': !showHiddenCategories,
-    });
+    setShowHiddenCategoriesPref(!showHiddenCategories);
   };
 
   return (
@@ -1245,7 +1233,7 @@ export function BudgetTable({
             />
           )}
           <View style={{ flex: 1 }} />
-          {(show3Cols || showBudgetedCol) && (
+          {(show3Cols || !showSpentColumn) && (
             <Button
               type="bare"
               disabled={show3Cols}
@@ -1255,7 +1243,7 @@ export function BudgetTable({
                 padding: '0 8px',
                 margin: '0 -8px',
                 background:
-                  showBudgetedCol && !show3Cols
+                  !showSpentColumn && !show3Cols
                     ? `linear-gradient(-45deg, ${theme.formInputBackgroundSelection} 8px, transparent 0)`
                     : null,
               }}
@@ -1292,7 +1280,7 @@ export function BudgetTable({
               </View>
             </Button>
           )}
-          {(show3Cols || !showBudgetedCol) && (
+          {(show3Cols || showSpentColumn) && (
             <Button
               type="bare"
               disabled={show3Cols}
@@ -1300,7 +1288,7 @@ export function BudgetTable({
               style={{
                 ...buttonStyle,
                 background:
-                  !showBudgetedCol && !show3Cols
+                  showSpentColumn && !show3Cols
                     ? `linear-gradient(45deg, ${theme.formInputBackgroundSelection} 8px, transparent 0)`
                     : null,
               }}
@@ -1372,7 +1360,7 @@ export function BudgetTable({
               <BudgetGroups
                 type={type}
                 categoryGroups={categoryGroups}
-                showBudgetedCol={showBudgetedCol}
+                showBudgetedCol={!showSpentColumn}
                 show3Cols={show3Cols}
                 showHiddenCategories={showHiddenCategories}
                 // gestures={gestures}
@@ -1407,7 +1395,7 @@ export function BudgetTable({
               <BudgetGroups
                 type={type}
                 categoryGroups={categoryGroups}
-                showBudgetedCol={showBudgetedCol}
+                showBudgetedCol={!showSpentColumn}
                 show3Cols={show3Cols}
                 showHiddenCategories={showHiddenCategories}
                 // gestures={gestures}
diff --git a/packages/desktop-client/src/components/budget/MonthCountSelector.tsx b/packages/desktop-client/src/components/budget/MonthCountSelector.tsx
index 737dcdc69..d64ed0082 100644
--- a/packages/desktop-client/src/components/budget/MonthCountSelector.tsx
+++ b/packages/desktop-client/src/components/budget/MonthCountSelector.tsx
@@ -22,7 +22,7 @@ function Calendar({ color, onClick }: CalendarProps) {
 
 type MonthCountSelectorProps = {
   maxMonths: number;
-  onChange: (value: number) => Promise<void>;
+  onChange: (value: number) => void;
 };
 
 export function MonthCountSelector({
diff --git a/packages/desktop-client/src/components/budget/index.tsx b/packages/desktop-client/src/components/budget/index.tsx
index ea263830d..724a969c2 100644
--- a/packages/desktop-client/src/components/budget/index.tsx
+++ b/packages/desktop-client/src/components/budget/index.tsx
@@ -7,35 +7,31 @@ import React, {
   useEffect,
   useRef,
 } from 'react';
-import { useSelector } from 'react-redux';
-import {
-  type NavigateFunction,
-  type PathMatch,
-  useLocation,
-  useMatch,
-} from 'react-router-dom';
-
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-import { useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider';
-import { send, listen } from 'loot-core/src/platform/client/fetch';
+import { useDispatch } from 'react-redux';
+
 import {
-  addCategory,
+  addNotification,
+  applyBudgetAction,
+  createCategory,
+  createGroup,
+  deleteCategory,
+  deleteGroup,
+  getCategories,
+  loadPrefs,
   moveCategory,
   moveCategoryGroup,
+  pushModal,
   updateCategory,
-  deleteCategory,
-  addGroup,
   updateGroup,
-  deleteGroup,
-} from 'loot-core/src/shared/categories';
+} from 'loot-core/src/client/actions';
+import { useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider';
+import { send, listen } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
-import { type GlobalPrefs, type LocalPrefs } from 'loot-core/src/types/prefs';
-import { type CategoryGroupEntity } from 'loot-core/types/models';
 
-import { type BoundActions, useActions } from '../../hooks/useActions';
 import { useCategories } from '../../hooks/useCategories';
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
+import { useGlobalPref } from '../../hooks/useGlobalPref';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { useNavigate } from '../../hooks/useNavigate';
 import { styles } from '../../style';
 import { View } from '../common/View';
@@ -75,62 +71,41 @@ type RolloverComponents = {
 
 type BudgetProps = {
   accountId?: string;
-  startMonth: LocalPrefs['budget.startMonth'];
-  collapsedPrefs: LocalPrefs['budget.collapsed'];
-  summaryCollapsed: LocalPrefs['budget.summaryCollapsed'];
-  budgetType: LocalPrefs['budgetType'];
-  maxMonths: GlobalPrefs['maxMonths'];
-  categoryGroups: CategoryGroupEntity[];
   reportComponents: ReportComponents;
   rolloverComponents: RolloverComponents;
   titlebar: TitlebarContextValue;
-  match: PathMatch<string>;
-  spreadsheet: ReturnType<typeof useSpreadsheet>;
-  navigate: NavigateFunction;
-  getCategories: BoundActions['getCategories'];
-  savePrefs: BoundActions['savePrefs'];
-  createCategory: BoundActions['createCategory'];
-  updateCategory: BoundActions['updateCategory'];
-  pushModal: BoundActions['pushModal'];
-  deleteCategory: BoundActions['deleteCategory'];
-  createGroup: BoundActions['createGroup'];
-  updateGroup: BoundActions['updateGroup'];
-  deleteGroup: BoundActions['deleteGroup'];
-  applyBudgetAction: BoundActions['applyBudgetAction'];
-  moveCategory: BoundActions['moveCategory'];
-  moveCategoryGroup: BoundActions['moveCategoryGroup'];
-  loadPrefs: BoundActions['loadPrefs'];
-  addNotification: BoundActions['addNotification'];
 };
 
 function BudgetInner(props: BudgetProps) {
   const currentMonth = monthUtils.currentMonth();
   const tableRef = useRef(null);
-
-  const [initialized, setInitialized] = useState(false);
-  const [prewarmStartMonth, setPrewarmStartMonth] = useState(
-    props.startMonth || currentMonth,
+  const spreadsheet = useSpreadsheet();
+  const dispatch = useDispatch();
+  const navigate = useNavigate();
+  const [_startMonth, setBudgetStartMonthPref] =
+    useLocalPref('budget.startMonth');
+  const startMonth = _startMonth || currentMonth;
+  const [summaryCollapsed, setSummaryCollapsedPref] = useLocalPref(
+    'budget.summaryCollapsed',
   );
+  const [_budgetType] = useLocalPref('budgetType');
+  const budgetType = _budgetType || 'rollover';
+  const [_maxMonths] = useGlobalPref('maxMonths');
+  const maxMonths = _maxMonths || 1;
 
-  const [newCategoryForGroup, setNewCategoryForGroup] = useState(null);
-  const [isAddingGroup, setIsAddingGroup] = useState(false);
-  const [collapsed, setCollapsed] = useState(props.collapsedPrefs || []);
+  const [initialized, setInitialized] = useState(false);
   const [bounds, setBounds] = useState({
     start: currentMonth,
     end: currentMonth,
   });
-  const [categoryGroups, setCategoryGroups] = useState(null);
-  const [summaryCollapsed, setSummaryCollapsed] = useState(
-    props.summaryCollapsed,
-  );
+  const { grouped: categoryGroups } = useCategories();
 
-  async function loadCategories() {
-    const result = await props.getCategories();
-    setCategoryGroups(result.grouped);
+  function loadCategories() {
+    dispatch(getCategories());
   }
 
   useEffect(() => {
-    const { titlebar, budgetType } = props;
+    const { titlebar } = props;
 
     async function run() {
       loadCategories();
@@ -140,9 +115,9 @@ function BudgetInner(props: BudgetProps) {
 
       await prewarmAllMonths(
         budgetType,
-        props.spreadsheet,
+        spreadsheet,
         { start, end },
-        prewarmStartMonth,
+        startMonth,
       );
 
       setInitialized(true);
@@ -187,10 +162,6 @@ function BudgetInner(props: BudgetProps) {
     };
   }, []);
 
-  useEffect(() => {
-    props.savePrefs({ 'budget.collapsed': collapsed });
-  }, [collapsed]);
-
   useEffect(() => {
     send('get-budget-bounds').then(({ start, end }) => {
       if (bounds.start !== start || bounds.end !== end) {
@@ -200,12 +171,10 @@ function BudgetInner(props: BudgetProps) {
   }, [props.accountId]);
 
   const onMonthSelect = async (month, numDisplayed) => {
-    setPrewarmStartMonth(month);
+    setBudgetStartMonthPref(month);
 
     const warmingMonth = month;
 
-    const startMonth = props.startMonth || currentMonth;
-
     // We could be smarter about this, but this is a good start. We
     // optimize for the case where users press the left/right button
     // to move between months. This loads the month data all at once
@@ -215,51 +184,37 @@ function BudgetInner(props: BudgetProps) {
     if (month < startMonth) {
       // pre-warm prev month
       await prewarmMonth(
-        props.budgetType,
-        props.spreadsheet,
+        budgetType,
+        spreadsheet,
         monthUtils.subMonths(month, 1),
       );
     } else if (month > startMonth) {
       // pre-warm next month
       await prewarmMonth(
-        props.budgetType,
-        props.spreadsheet,
+        budgetType,
+        spreadsheet,
         monthUtils.addMonths(month, numDisplayed),
       );
     }
 
     if (warmingMonth === month) {
-      props.savePrefs({ 'budget.startMonth': month });
+      setBudgetStartMonthPref(month);
     }
   };
 
-  const onShowNewCategory = groupId => {
-    setNewCategoryForGroup(groupId);
-    setCollapsed(state => state.filter(c => c !== groupId));
-  };
-
-  const onHideNewCategory = () => {
-    setNewCategoryForGroup(null);
-  };
-
-  const onShowNewGroup = () => {
-    setIsAddingGroup(true);
-  };
-
-  const onHideNewGroup = () => {
-    setIsAddingGroup(false);
-  };
-
   const categoryNameAlreadyExistsNotification = name => {
-    props.addNotification({
-      type: 'error',
-      message: `Category ‘${name}’ already exists in group (May be Hidden)`,
-    });
+    dispatch(
+      addNotification({
+        type: 'error',
+        message: `Category ‘${name}’ already exists in group (May be Hidden)`,
+      }),
+    );
   };
 
   const onSaveCategory = async category => {
+    const cats = await send('get-categories');
     const exists =
-      (await props.getCategories()).grouped
+      cats.grouped
         .filter(g => g.id === category.cat_group)[0]
         .categories.filter(
           c => c.name.toUpperCase() === category.name.toUpperCase(),
@@ -273,24 +228,16 @@ function BudgetInner(props: BudgetProps) {
     }
 
     if (category.id === 'new') {
-      const id = await props.createCategory(
-        category.name,
-        category.cat_group,
-        category.is_income,
-        category.hidden,
-      );
-
-      setNewCategoryForGroup(null);
-      setCategoryGroups(state =>
-        addCategory(state, {
-          ...category,
-          is_income: category.is_income ? 1 : 0,
-          id,
-        }),
+      dispatch(
+        createCategory(
+          category.name,
+          category.cat_group,
+          category.is_income,
+          category.hidden,
+        ),
       );
     } else {
-      props.updateCategory(category);
-      setCategoryGroups(state => updateCategory(state, category));
+      dispatch(updateCategory(category));
     }
   };
 
@@ -298,55 +245,26 @@ function BudgetInner(props: BudgetProps) {
     const mustTransfer = await send('must-category-transfer', { id });
 
     if (mustTransfer) {
-      props.pushModal('confirm-category-delete', {
-        category: id,
-        onDelete: transferCategory => {
-          if (id !== transferCategory) {
-            props.deleteCategory(id, transferCategory);
-
-            setCategoryGroups(state => deleteCategory(state, id));
-          }
-        },
-      });
+      dispatch(
+        pushModal('confirm-category-delete', {
+          category: id,
+          onDelete: transferCategory => {
+            if (id !== transferCategory) {
+              dispatch(deleteCategory(id, transferCategory));
+            }
+          },
+        }),
+      );
     } else {
-      props.deleteCategory(id);
-
-      setCategoryGroups(state => deleteCategory(state, id));
+      dispatch(deleteCategory(id));
     }
   };
 
-  const groupNameAlreadyExistsNotification = group => {
-    props.addNotification({
-      type: 'error',
-      message: `A ${group.hidden ? 'hidden ' : ''}’${group.name}’ category group already exists.`,
-    });
-  };
-
-  const onSaveGroup = async group => {
-    const categories = await props.getCategories();
-    const matchingGroups = categories.grouped
-      .filter(g => g.name.toUpperCase() === group.name.toUpperCase())
-      .filter(g => group.id === 'new' || group.id !== g.id);
-
-    if (matchingGroups.length > 0) {
-      groupNameAlreadyExistsNotification(matchingGroups[0]);
-      return;
-    }
-
+  const onSaveGroup = group => {
     if (group.id === 'new') {
-      const id = await props.createGroup(group.name);
-      setIsAddingGroup(false);
-      setCategoryGroups(state =>
-        addGroup(state, {
-          ...group,
-          is_income: 0,
-          categories: group.categories || [],
-          id,
-        }),
-      );
+      dispatch(createGroup(group.name));
     } else {
-      props.updateGroup(group);
-      setCategoryGroups(state => updateGroup(state, group));
+      dispatch(updateGroup(group));
     }
   };
 
@@ -362,27 +280,25 @@ function BudgetInner(props: BudgetProps) {
     }
 
     if (mustTransfer) {
-      props.pushModal('confirm-category-delete', {
-        group: id,
-        onDelete: transferCategory => {
-          props.deleteGroup(id, transferCategory);
-
-          setCategoryGroups(state => deleteGroup(state, id));
-        },
-      });
+      dispatch(
+        pushModal('confirm-category-delete', {
+          group: id,
+          onDelete: transferCategory => {
+            dispatch(deleteGroup(id, transferCategory));
+          },
+        }),
+      );
     } else {
-      props.deleteGroup(id);
-
-      setCategoryGroups(state => deleteGroup(state, id));
+      dispatch(deleteGroup(id));
     }
   };
 
   const onBudgetAction = (month, type, args) => {
-    props.applyBudgetAction(month, type, args);
+    dispatch(applyBudgetAction(month, type, args));
   };
 
   const onShowActivity = (categoryName, categoryId, month) => {
-    props.navigate('/accounts', {
+    navigate('/accounts', {
       state: {
         goBack: true,
         filterName: `${categoryName} (${monthUtils.format(
@@ -398,7 +314,7 @@ function BudgetInner(props: BudgetProps) {
   };
 
   const onReorderCategory = async sortInfo => {
-    const cats = await props.getCategories();
+    const cats = await send('get-categories');
     const moveCandidate = cats.list.filter(c => c.id === sortInfo.id)[0];
     const exists =
       cats.grouped
@@ -413,23 +329,15 @@ function BudgetInner(props: BudgetProps) {
       return;
     }
 
-    props.moveCategory(sortInfo.id, sortInfo.groupId, sortInfo.targetId);
-    setCategoryGroups(state =>
-      moveCategory(state, sortInfo.id, sortInfo.groupId, sortInfo.targetId),
-    );
+    dispatch(moveCategory(sortInfo.id, sortInfo.groupId, sortInfo.targetId));
   };
 
   const onReorderGroup = async sortInfo => {
-    props.moveCategoryGroup(sortInfo.id, sortInfo.targetId);
-    setCategoryGroups(state =>
-      moveCategoryGroup(state, sortInfo.id, sortInfo.targetId),
-    );
+    dispatch(moveCategoryGroup(sortInfo.id, sortInfo.targetId));
   };
 
   const onToggleCollapse = () => {
-    const collapsed = !summaryCollapsed;
-    setSummaryCollapsed(collapsed);
-    props.savePrefs({ 'budget.summaryCollapsed': collapsed });
+    setSummaryCollapsedPref(!summaryCollapsed);
   };
 
   const onTitlebarEvent = async ({ type, payload }: TitlebarMessage) => {
@@ -437,10 +345,12 @@ function BudgetInner(props: BudgetProps) {
       case SWITCH_BUDGET_MESSAGE_TYPE: {
         await switchBudgetType(
           payload.newBudgetType,
-          props.spreadsheet,
+          spreadsheet,
           bounds,
-          prewarmStartMonth,
-          () => props.loadPrefs(),
+          startMonth,
+          async () => {
+            dispatch(loadPrefs());
+          },
         );
         break;
       }
@@ -448,23 +358,14 @@ function BudgetInner(props: BudgetProps) {
     }
   };
 
-  const {
-    maxMonths: originalMaxMonths,
-    budgetType: type,
-    reportComponents,
-    rolloverComponents,
-  } = props;
-
-  const maxMonths = originalMaxMonths || 1;
+  const { reportComponents, rolloverComponents } = props;
 
   if (!initialized || !categoryGroups) {
     return null;
   }
 
-  const startMonth = props.startMonth || currentMonth;
-
   let table;
-  if (type === 'report') {
+  if (budgetType === 'report') {
     table = (
       <ReportProvider
         summaryCollapsed={summaryCollapsed}
@@ -473,22 +374,13 @@ function BudgetInner(props: BudgetProps) {
       >
         <DynamicBudgetTable
           ref={tableRef}
-          type={type}
-          categoryGroups={categoryGroups}
-          prewarmStartMonth={prewarmStartMonth}
+          type={budgetType}
+          prewarmStartMonth={startMonth}
           startMonth={startMonth}
           monthBounds={bounds}
           maxMonths={maxMonths}
-          collapsed={collapsed}
-          setCollapsed={setCollapsed}
-          newCategoryForGroup={newCategoryForGroup}
-          isAddingGroup={isAddingGroup}
           dataComponents={reportComponents}
           onMonthSelect={onMonthSelect}
-          onShowNewCategory={onShowNewCategory}
-          onHideNewCategory={onHideNewCategory}
-          onShowNewGroup={onShowNewGroup}
-          onHideNewGroup={onHideNewGroup}
           onDeleteCategory={onDeleteCategory}
           onDeleteGroup={onDeleteGroup}
           onSaveCategory={onSaveCategory}
@@ -503,29 +395,19 @@ function BudgetInner(props: BudgetProps) {
   } else {
     table = (
       <RolloverContext
-        categoryGroups={categoryGroups}
         summaryCollapsed={summaryCollapsed}
         onBudgetAction={onBudgetAction}
         onToggleSummaryCollapse={onToggleCollapse}
       >
         <DynamicBudgetTable
           ref={tableRef}
-          type={type}
-          categoryGroups={categoryGroups}
-          prewarmStartMonth={prewarmStartMonth}
+          type={budgetType}
+          prewarmStartMonth={startMonth}
           startMonth={startMonth}
           monthBounds={bounds}
           maxMonths={maxMonths}
-          collapsed={collapsed}
-          setCollapsed={setCollapsed}
-          newCategoryForGroup={newCategoryForGroup}
-          isAddingGroup={isAddingGroup}
           dataComponents={rolloverComponents}
           onMonthSelect={onMonthSelect}
-          onShowNewCategory={onShowNewCategory}
-          onHideNewCategory={onHideNewCategory}
-          onShowNewGroup={onShowNewGroup}
-          onHideNewGroup={onHideNewGroup}
           onDeleteCategory={onDeleteCategory}
           onDeleteGroup={onDeleteGroup}
           onSaveCategory={onSaveCategory}
@@ -553,32 +435,7 @@ const RolloverBudgetSummary = memo<{ month: string }>(props => {
 });
 
 export function Budget() {
-  const startMonth = useSelector<
-    State,
-    PrefsState['local']['budget.startMonth']
-  >(state => state.prefs.local['budget.startMonth']);
-  const collapsedPrefs = useSelector<
-    State,
-    PrefsState['local']['budget.collapsed']
-  >(state => state.prefs.local['budget.collapsed']);
-  const summaryCollapsed = useSelector<
-    State,
-    PrefsState['local']['budget.summaryCollapsed']
-  >(state => state.prefs.local['budget.summaryCollapsed']);
-  const budgetType = useSelector<State, PrefsState['local']['budgetType']>(
-    state => state.prefs.local.budgetType || 'rollover',
-  );
-  const maxMonths = useSelector<State, PrefsState['global']['maxMonths']>(
-    state => state.prefs.global.maxMonths,
-  );
-  const { grouped: categoryGroups } = useCategories();
-
-  const actions = useActions();
-  const spreadsheet = useSpreadsheet();
   const titlebar = useContext(TitlebarContext);
-  const location = useLocation();
-  const match = useMatch(location.pathname);
-  const navigate = useNavigate();
 
   const reportComponents = useMemo<ReportComponents>(
     () => ({
@@ -620,19 +477,9 @@ export function Budget() {
       }}
     >
       <BudgetInner
-        startMonth={startMonth}
-        collapsedPrefs={collapsedPrefs}
-        summaryCollapsed={summaryCollapsed}
-        budgetType={budgetType}
-        maxMonths={maxMonths}
-        categoryGroups={categoryGroups}
-        {...actions}
         reportComponents={reportComponents}
         rolloverComponents={rolloverComponents}
-        spreadsheet={spreadsheet}
         titlebar={titlebar}
-        navigate={navigate}
-        match={match}
       />
     </View>
   );
diff --git a/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx b/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx
index 636953b16..fcbc714cd 100644
--- a/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx
+++ b/packages/desktop-client/src/components/budget/rollover/RolloverContext.tsx
@@ -6,14 +6,12 @@ import * as monthUtils from 'loot-core/src/shared/months';
 const Context = createContext(null);
 
 type RolloverContextProps = {
-  categoryGroups: unknown[];
   summaryCollapsed: boolean;
   onBudgetAction: (idx: number, action: string, arg?: unknown) => void;
   onToggleSummaryCollapse: () => void;
   children: ReactNode;
 };
 export function RolloverContext({
-  categoryGroups,
   summaryCollapsed,
   onBudgetAction,
   onToggleSummaryCollapse,
@@ -25,7 +23,6 @@ export function RolloverContext({
     <Context.Provider
       value={{
         currentMonth,
-        categoryGroups,
         summaryCollapsed,
         onBudgetAction,
         onToggleSummaryCollapse,
diff --git a/packages/desktop-client/src/components/filters/AppliedFilters.tsx b/packages/desktop-client/src/components/filters/AppliedFilters.tsx
index 1f5ead431..eac0510a1 100644
--- a/packages/desktop-client/src/components/filters/AppliedFilters.tsx
+++ b/packages/desktop-client/src/components/filters/AppliedFilters.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 
-import { type RuleConditionEntity } from 'loot-core/types/models';
+import { type RuleConditionEntity } from 'loot-core/src/types/models';
 
 import { View } from '../common/View';
 
diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.jsx b/packages/desktop-client/src/components/filters/FiltersMenu.jsx
index f4650c5a4..18889c515 100644
--- a/packages/desktop-client/src/components/filters/FiltersMenu.jsx
+++ b/packages/desktop-client/src/components/filters/FiltersMenu.jsx
@@ -1,5 +1,4 @@
 import React, { useState, useRef, useEffect, useReducer } from 'react';
-import { useSelector } from 'react-redux';
 
 import { FocusScope } from '@react-aria/focus';
 import {
@@ -21,6 +20,7 @@ import {
 } from 'loot-core/src/shared/rules';
 import { titleFirst } from 'loot-core/src/shared/util';
 
+import { useDateFormat } from '../../hooks/useDateFormat';
 import { theme } from '../../style';
 import { Button } from '../common/Button';
 import { HoverTarget } from '../common/HoverTarget';
@@ -246,11 +246,7 @@ function ConfigureField({
 export function FilterButton({ onApply, compact, hover }) {
   const filters = useFilters();
 
-  const { dateFormat } = useSelector(state => {
-    return {
-      dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy',
-    };
-  });
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
 
   const [state, dispatch] = useReducer(
     (state, action) => {
diff --git a/packages/desktop-client/src/components/modals/CloseAccount.tsx b/packages/desktop-client/src/components/modals/CloseAccount.tsx
index e5bc05b8d..9266c584b 100644
--- a/packages/desktop-client/src/components/modals/CloseAccount.tsx
+++ b/packages/desktop-client/src/components/modals/CloseAccount.tsx
@@ -2,12 +2,11 @@
 import React, { useState } from 'react';
 
 import { integerToCurrency } from 'loot-core/src/shared/util';
-import {
-  type AccountEntity,
-  type CategoryGroupEntity,
-} from 'loot-core/src/types/models';
+import { type AccountEntity } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { type BoundActions } from '../../hooks/useActions';
+import { useCategories } from '../../hooks/useCategories';
 import { theme } from '../../style';
 import { AccountAutocomplete } from '../autocomplete/AccountAutocomplete';
 import { CategoryAutocomplete } from '../autocomplete/CategoryAutocomplete';
@@ -35,8 +34,6 @@ function needsCategory(
 
 type CloseAccountProps = {
   account: AccountEntity;
-  accounts: AccountEntity[];
-  categoryGroups: CategoryGroupEntity[];
   balance: number;
   canDelete: boolean;
   actions: BoundActions;
@@ -45,8 +42,6 @@ type CloseAccountProps = {
 
 export function CloseAccount({
   account,
-  accounts,
-  categoryGroups,
   balance,
   canDelete,
   actions,
@@ -58,6 +53,8 @@ export function CloseAccount({
 
   const [transferError, setTransferError] = useState(false);
   const [categoryError, setCategoryError] = useState(false);
+  const accounts = useAccounts().filter(a => a.closed === 0);
+  const { grouped: categoryGroups } = useCategories();
 
   return (
     <Modal
diff --git a/packages/desktop-client/src/components/modals/ConfirmCategoryDelete.tsx b/packages/desktop-client/src/components/modals/ConfirmCategoryDelete.tsx
index 803e95003..a448f351c 100644
--- a/packages/desktop-client/src/components/modals/ConfirmCategoryDelete.tsx
+++ b/packages/desktop-client/src/components/modals/ConfirmCategoryDelete.tsx
@@ -1,8 +1,7 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
 
-import { type CategoryGroupEntity } from 'loot-core/src/types/models';
-
+import { useCategories } from '../../hooks/useCategories';
 import { theme } from '../../style';
 import { CategoryAutocomplete } from '../autocomplete/CategoryAutocomplete';
 import { Block } from '../common/Block';
@@ -14,21 +13,22 @@ import { type CommonModalProps } from '../Modals';
 
 type ConfirmCategoryDeleteProps = {
   modalProps: CommonModalProps;
-  category: CategoryGroupEntity;
-  group: CategoryGroupEntity;
-  categoryGroups: CategoryGroupEntity[];
+  category: string;
+  group: string;
   onDelete: (categoryId: string) => void;
 };
 
 export function ConfirmCategoryDelete({
   modalProps,
-  category,
-  group,
-  categoryGroups,
+  group: groupId,
+  category: categoryId,
   onDelete,
 }: ConfirmCategoryDeleteProps) {
   const [transferCategory, setTransferCategory] = useState<string | null>(null);
   const [error, setError] = useState<string | null>(null);
+  const { grouped: categoryGroups, list: categories } = useCategories();
+  const group = categoryGroups.find(g => g.id === groupId);
+  const category = categories.find(c => c.id === categoryId);
 
   const renderError = (error: string) => {
     let msg: string;
diff --git a/packages/desktop-client/src/components/modals/EditField.jsx b/packages/desktop-client/src/components/modals/EditField.jsx
index fa2b492c4..0e2d3f1ff 100644
--- a/packages/desktop-client/src/components/modals/EditField.jsx
+++ b/packages/desktop-client/src/components/modals/EditField.jsx
@@ -1,13 +1,15 @@
 import React from 'react';
-import { useSelector } from 'react-redux';
 
 import { parseISO, format as formatDate, parse as parseDate } from 'date-fns';
 
 import { currentDay, dayFromDate } from 'loot-core/src/shared/months';
 import { amountToInteger } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useActions } from '../../hooks/useActions';
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { usePayees } from '../../hooks/usePayees';
 import { SvgAdd } from '../../icons/v1';
 import { useResponsive } from '../../ResponsiveProvider';
 import { styles, theme } from '../../style';
@@ -38,12 +40,10 @@ function CreatePayeeIcon(props) {
 }
 
 export function EditField({ modalProps, name, onSubmit, onClose }) {
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
   const { grouped: categoryGroups } = useCategories();
-  const accounts = useSelector(state => state.queries.accounts);
-  const payees = useSelector(state => state.queries.payees);
+  const accounts = useAccounts();
+  const payees = usePayees();
 
   const { createPayee } = useActions();
 
diff --git a/packages/desktop-client/src/components/modals/EditRule.jsx b/packages/desktop-client/src/components/modals/EditRule.jsx
index e7ebb2094..83cd8799d 100644
--- a/packages/desktop-client/src/components/modals/EditRule.jsx
+++ b/packages/desktop-client/src/components/modals/EditRule.jsx
@@ -1,5 +1,5 @@
 import React, { useState, useEffect, useRef, useCallback } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
+import { useDispatch } from 'react-redux';
 
 import { v4 as uuid } from 'uuid';
 
@@ -28,6 +28,7 @@ import {
   amountToInteger,
 } from 'loot-core/src/shared/util';
 
+import { useDateFormat } from '../../hooks/useDateFormat';
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
 import { useSelected, SelectedProvider } from '../../hooks/useSelected';
 import { SvgDelete, SvgAdd, SvgSubtract } from '../../icons/v0';
@@ -268,9 +269,7 @@ function formatAmount(amount) {
 }
 
 function ScheduleDescription({ id }) {
-  const dateFormat = useSelector(state => {
-    return state.prefs.local.dateFormat || 'MM/dd/yyyy';
-  });
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
   const scheduleData = useSchedules({
     transform: useCallback(q => q.filter({ id }), []),
   });
diff --git a/packages/desktop-client/src/components/modals/ImportTransactions.jsx b/packages/desktop-client/src/components/modals/ImportTransactions.jsx
index 89a564b70..3bd05e300 100644
--- a/packages/desktop-client/src/components/modals/ImportTransactions.jsx
+++ b/packages/desktop-client/src/components/modals/ImportTransactions.jsx
@@ -1,5 +1,4 @@
 import React, { useState, useEffect, useMemo } from 'react';
-import { useSelector } from 'react-redux';
 
 import * as d from 'date-fns';
 
@@ -11,6 +10,8 @@ import {
 } from 'loot-core/src/shared/util';
 
 import { useActions } from '../../hooks/useActions';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { useLocalPrefs } from '../../hooks/useLocalPrefs';
 import { theme, styles } from '../../style';
 import { Button, ButtonWithLoading } from '../common/Button';
 import { Input } from '../common/Input';
@@ -703,10 +704,8 @@ function FieldMappings({
 }
 
 export function ImportTransactions({ modalProps, options }) {
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
-  const prefs = useSelector(state => state.prefs.local);
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+  const prefs = useLocalPrefs();
   const { parseTransactions, importTransactions, getPayees, savePrefs } =
     useActions();
 
diff --git a/packages/desktop-client/src/components/modals/LoadBackup.jsx b/packages/desktop-client/src/components/modals/LoadBackup.jsx
index d430346b2..e09f78332 100644
--- a/packages/desktop-client/src/components/modals/LoadBackup.jsx
+++ b/packages/desktop-client/src/components/modals/LoadBackup.jsx
@@ -2,6 +2,7 @@ import React, { Component, useState, useEffect } from 'react';
 
 import { send, listen, unlisten } from 'loot-core/src/platform/client/fetch';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { theme } from '../../style';
 import { Block } from '../common/Block';
 import { Button } from '../common/Button';
@@ -55,10 +56,12 @@ export function LoadBackup({
   modalProps,
 }) {
   const [backups, setBackups] = useState([]);
+  const [prefsBudgetId] = useLocalPref('id');
+  const budgetIdToLoad = budgetId || prefsBudgetId;
 
   useEffect(() => {
-    send('backups-get', { id: budgetId }).then(setBackups);
-  }, [budgetId]);
+    send('backups-get', { id: budgetIdToLoad }).then(setBackups);
+  }, [budgetIdToLoad]);
 
   useEffect(() => {
     if (watchUpdates) {
@@ -93,7 +96,9 @@ export function LoadBackup({
                 </Block>
                 <Button
                   type="primary"
-                  onClick={() => actions.loadBackup(budgetId, latestBackup.id)}
+                  onClick={() =>
+                    actions.loadBackup(budgetIdToLoad, latestBackup.id)
+                  }
                 >
                   Revert to original version
                 </Button>
@@ -125,7 +130,7 @@ export function LoadBackup({
           ) : (
             <BackupTable
               backups={previousBackups}
-              onSelect={id => actions.loadBackup(budgetId, id)}
+              onSelect={id => actions.loadBackup(budgetIdToLoad, id)}
             />
           )}
         </View>
diff --git a/packages/desktop-client/src/components/modals/MergeUnusedPayees.jsx b/packages/desktop-client/src/components/modals/MergeUnusedPayees.jsx
index 5e36e4f9d..33ca3d703 100644
--- a/packages/desktop-client/src/components/modals/MergeUnusedPayees.jsx
+++ b/packages/desktop-client/src/components/modals/MergeUnusedPayees.jsx
@@ -4,6 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';
 import { replaceModal } from 'loot-core/src/client/actions/modals';
 import { send } from 'loot-core/src/platform/client/fetch';
 
+import { usePayees } from '../../hooks/usePayees';
 import { theme } from '../../style';
 import { Information } from '../alerts';
 import { Button } from '../common/Button';
@@ -15,10 +16,8 @@ import { View } from '../common/View';
 const highlightStyle = { color: theme.pageTextPositive };
 
 export function MergeUnusedPayees({ modalProps, payeeIds, targetPayeeId }) {
-  const { payees: allPayees, modalStack } = useSelector(state => ({
-    payees: state.queries.payees,
-    modalStack: state.modals.modalStack,
-  }));
+  const allPayees = usePayees();
+  const modalStack = useSelector(state => state.modals.modalStack);
   const isEditingRule = !!modalStack.find(m => m.name === 'edit-rule');
   const dispatch = useDispatch();
   const [shouldCreateRule, setShouldCreateRule] = useState(true);
diff --git a/packages/desktop-client/src/components/modals/SelectLinkedAccounts.jsx b/packages/desktop-client/src/components/modals/SelectLinkedAccounts.jsx
index 8d8d82475..8f74791de 100644
--- a/packages/desktop-client/src/components/modals/SelectLinkedAccounts.jsx
+++ b/packages/desktop-client/src/components/modals/SelectLinkedAccounts.jsx
@@ -1,5 +1,6 @@
 import React, { useState } from 'react';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { theme } from '../../style';
 import { Autocomplete } from '../autocomplete/Autocomplete';
 import { Button } from '../common/Button';
@@ -14,10 +15,10 @@ export function SelectLinkedAccounts({
   modalProps,
   requisitionId,
   externalAccounts,
-  localAccounts,
   actions,
   syncSource,
 }) {
+  const localAccounts = useAccounts().filter(a => a.closed === 0);
   const [chosenAccounts, setChosenAccounts] = useState(() => {
     return Object.fromEntries(
       localAccounts
diff --git a/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx b/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx
index 80aada7a8..eb04d7e86 100644
--- a/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx
+++ b/packages/desktop-client/src/components/modals/SwitchBudgetType.tsx
@@ -1,10 +1,7 @@
 // @ts-strict-ignore
 import React from 'react';
-import { useSelector } from 'react-redux';
-
-import { type State } from 'loot-core/src/client/state-types';
-import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { Button } from '../common/Button';
 import { ExternalLink } from '../common/ExternalLink';
 import { Modal } from '../common/Modal';
@@ -21,9 +18,7 @@ export function SwitchBudgetType({
   modalProps,
   onSwitch,
 }: SwitchBudgetTypeProps) {
-  const budgetType = useSelector<State, PrefsState['local']['budgetType']>(
-    state => state.prefs.local.budgetType,
-  );
+  const [budgetType] = useLocalPref('budgetType');
   return (
     <Modal title="Switch budget type?" {...modalProps}>
       {() => (
diff --git a/packages/desktop-client/src/components/payees/ManagePayeesWithData.jsx b/packages/desktop-client/src/components/payees/ManagePayeesWithData.jsx
index a828c5e73..55ea8bc78 100644
--- a/packages/desktop-client/src/components/payees/ManagePayeesWithData.jsx
+++ b/packages/desktop-client/src/components/payees/ManagePayeesWithData.jsx
@@ -6,11 +6,12 @@ import { applyChanges } from 'loot-core/src/shared/util';
 
 import { useActions } from '../../hooks/useActions';
 import { useCategories } from '../../hooks/useCategories';
+import { usePayees } from '../../hooks/usePayees';
 
 import { ManagePayees } from './ManagePayees';
 
 export function ManagePayeesWithData({ initialSelectedIds }) {
-  const initialPayees = useSelector(state => state.queries.payees);
+  const initialPayees = usePayees();
   const lastUndoState = useSelector(state => state.app.lastUndoState);
   const { grouped: categoryGroups } = useCategories();
 
diff --git a/packages/desktop-client/src/components/reports/Overview.jsx b/packages/desktop-client/src/components/reports/Overview.jsx
index e0b8163d6..539aeda89 100644
--- a/packages/desktop-client/src/components/reports/Overview.jsx
+++ b/packages/desktop-client/src/components/reports/Overview.jsx
@@ -1,8 +1,8 @@
 import React from 'react';
-import { useSelector } from 'react-redux';
 
 import { useReports } from 'loot-core/src/client/data-hooks/reports';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
 import { styles } from '../../style';
 import { View } from '../common/View';
@@ -18,7 +18,7 @@ export function Overview() {
 
   const customReportsFeatureFlag = useFeatureFlag('customReports');
 
-  const accounts = useSelector(state => state.queries.accounts);
+  const accounts = useAccounts();
   return (
     <View
       style={{
diff --git a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx
index a261be8e3..54b142030 100644
--- a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx
@@ -13,13 +13,13 @@ import {
   ResponsiveContainer,
 } from 'recharts';
 
-import { usePrivacyMode } from 'loot-core/src/client/privacy';
 import {
   amountToCurrency,
   amountToCurrencyNoDecimal,
 } from 'loot-core/src/shared/util';
 import { type GroupedEntity } from 'loot-core/src/types/models/reports';
 
+import { usePrivacyMode } from '../../../hooks/usePrivacyMode';
 import { theme } from '../../../style';
 import { type CSSProperties } from '../../../style';
 import { AlignedText } from '../../common/AlignedText';
diff --git a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx
index 3d81b5ced..6263c6651 100644
--- a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx
@@ -15,13 +15,13 @@ import {
   ResponsiveContainer,
 } from 'recharts';
 
-import { usePrivacyMode } from 'loot-core/src/client/privacy';
 import {
   amountToCurrency,
   amountToCurrencyNoDecimal,
 } from 'loot-core/src/shared/util';
 import { type GroupedEntity } from 'loot-core/src/types/models/reports';
 
+import { usePrivacyMode } from '../../../hooks/usePrivacyMode';
 import { theme } from '../../../style';
 import { type CSSProperties } from '../../../style';
 import { AlignedText } from '../../common/AlignedText';
diff --git a/packages/desktop-client/src/components/reports/graphs/CashFlowGraph.tsx b/packages/desktop-client/src/components/reports/graphs/CashFlowGraph.tsx
index e186a70b6..8334fa9de 100644
--- a/packages/desktop-client/src/components/reports/graphs/CashFlowGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/CashFlowGraph.tsx
@@ -15,12 +15,12 @@ import {
   type TooltipProps,
 } from 'recharts';
 
-import { usePrivacyMode } from 'loot-core/src/client/privacy';
 import {
   amountToCurrency,
   amountToCurrencyNoDecimal,
 } from 'loot-core/src/shared/util';
 
+import { usePrivacyMode } from '../../../hooks/usePrivacyMode';
 import { theme } from '../../../style';
 import { AlignedText } from '../../common/AlignedText';
 import { chartTheme } from '../chart-theme';
diff --git a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx
index ab2fcf993..777f4be4c 100644
--- a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx
@@ -13,13 +13,13 @@ import {
   ResponsiveContainer,
 } from 'recharts';
 
-import { usePrivacyMode } from 'loot-core/src/client/privacy';
 import {
   amountToCurrency,
   amountToCurrencyNoDecimal,
 } from 'loot-core/src/shared/util';
 import { type GroupedEntity } from 'loot-core/src/types/models/reports';
 
+import { usePrivacyMode } from '../../../hooks/usePrivacyMode';
 import { theme } from '../../../style';
 import { type CSSProperties } from '../../../style';
 import { AlignedText } from '../../common/AlignedText';
diff --git a/packages/desktop-client/src/components/reports/reports/CustomReport.jsx b/packages/desktop-client/src/components/reports/reports/CustomReport.jsx
index f786572ef..139f4716f 100644
--- a/packages/desktop-client/src/components/reports/reports/CustomReport.jsx
+++ b/packages/desktop-client/src/components/reports/reports/CustomReport.jsx
@@ -1,18 +1,17 @@
 import React, { useState, useEffect, useMemo } from 'react';
-import { useSelector } from 'react-redux';
 import { useLocation } from 'react-router-dom';
 
 import * as d from 'date-fns';
 
-import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts';
-import { useCachedPayees } from 'loot-core/src/client/data-hooks/payees';
 import { send } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import { amountToCurrency } from 'loot-core/src/shared/util';
 
-import { useActions } from '../../../hooks/useActions';
+import { useAccounts } from '../../../hooks/useAccounts';
 import { useCategories } from '../../../hooks/useCategories';
 import { useFilters } from '../../../hooks/useFilters';
+import { useLocalPref } from '../../../hooks/useLocalPref';
+import { usePayees } from '../../../hooks/usePayees';
 import { theme, styles } from '../../../style';
 import { AlignedText } from '../../common/AlignedText';
 import { Block } from '../../common/Block';
@@ -36,13 +35,12 @@ import { fromDateRepr } from '../util';
 export function CustomReport() {
   const categories = useCategories();
 
-  const viewLegend =
-    useSelector(state => state.prefs.local?.reportsViewLegend) || false;
-  const viewSummary =
-    useSelector(state => state.prefs.local?.reportsViewSummary) || false;
-  const viewLabels =
-    useSelector(state => state.prefs.local?.reportsViewLabel) || false;
-  const { savePrefs } = useActions();
+  const [viewLegend = false, setViewLegendPref] =
+    useLocalPref('reportsViewLegend');
+  const [viewSummary = false, setViewSummaryPref] =
+    useLocalPref('reportsViewSummary');
+  const [viewLabels = false, setViewLabelsPref] =
+    useLocalPref('reportsViewLabel');
 
   const {
     filters,
@@ -126,8 +124,8 @@ export function CustomReport() {
   }, []);
 
   const balanceTypeOp = ReportOptions.balanceTypeMap.get(balanceType);
-  const payees = useCachedPayees();
-  const accounts = useCachedAccounts();
+  const payees = usePayees();
+  const accounts = useAccounts();
 
   const getGroupData = useMemo(() => {
     return createGroupedSpreadsheet({
@@ -235,13 +233,13 @@ export function CustomReport() {
 
   const onChangeViews = (viewType, status) => {
     if (viewType === 'viewLegend') {
-      savePrefs({ reportsViewLegend: status ?? !viewLegend });
+      setViewLegendPref(status ?? !viewLegend);
     }
     if (viewType === 'viewSummary') {
-      savePrefs({ reportsViewSummary: !viewSummary });
+      setViewSummaryPref(!viewSummary);
     }
     if (viewType === 'viewLabels') {
-      savePrefs({ reportsViewLabel: !viewLabels });
+      setViewLabelsPref(!viewLabels);
     }
   };
 
diff --git a/packages/desktop-client/src/components/reports/reports/NetWorth.jsx b/packages/desktop-client/src/components/reports/reports/NetWorth.jsx
index 5bdd779b2..4dbec9a8e 100644
--- a/packages/desktop-client/src/components/reports/reports/NetWorth.jsx
+++ b/packages/desktop-client/src/components/reports/reports/NetWorth.jsx
@@ -1,5 +1,4 @@
 import React, { useState, useEffect, useMemo } from 'react';
-import { useSelector } from 'react-redux';
 
 import * as d from 'date-fns';
 
@@ -7,6 +6,7 @@ import { send } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import { integerToCurrency } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../../hooks/useAccounts';
 import { useFilters } from '../../../hooks/useFilters';
 import { theme, styles } from '../../../style';
 import { Paragraph } from '../../common/Paragraph';
@@ -20,7 +20,7 @@ import { useReport } from '../useReport';
 import { fromDateRepr } from '../util';
 
 export function NetWorth() {
-  const accounts = useSelector(state => state.queries.accounts);
+  const accounts = useAccounts();
   const {
     filters,
     saved,
diff --git a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts
index 45efef476..c0b6e8f34 100644
--- a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts
+++ b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts
@@ -1,5 +1,5 @@
 // @ts-strict-ignore
-import { type GroupedEntity } from 'loot-core/types/models/reports';
+import { type GroupedEntity } from 'loot-core/src/types/models/reports';
 
 export function filterEmptyRows(
   showEmpty: boolean,
diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts
index 0adc9b119..f44cddf8c 100644
--- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts
+++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts
@@ -3,7 +3,7 @@ import { runQuery } from 'loot-core/src/client/query-helpers';
 import { send } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import { integerToAmount } from 'loot-core/src/shared/util';
-import { type GroupedEntity } from 'loot-core/types/models/reports';
+import { type GroupedEntity } from 'loot-core/src/types/models/reports';
 
 import { categoryLists } from '../ReportOptions';
 
diff --git a/packages/desktop-client/src/components/rules/ScheduleValue.tsx b/packages/desktop-client/src/components/rules/ScheduleValue.tsx
index 036d0a2ed..fb05b0b8f 100644
--- a/packages/desktop-client/src/components/rules/ScheduleValue.tsx
+++ b/packages/desktop-client/src/components/rules/ScheduleValue.tsx
@@ -1,12 +1,11 @@
 import React from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type QueriesState } from 'loot-core/client/state-types/queries';
 import { getPayeesById } from 'loot-core/src/client/reducers/queries';
 import { describeSchedule } from 'loot-core/src/shared/schedules';
 import { type ScheduleEntity } from 'loot-core/src/types/models';
 
+import { usePayees } from '../../hooks/usePayees';
+
 import { SchedulesQuery } from './SchedulesQuery';
 import { Value } from './Value';
 
@@ -15,9 +14,7 @@ type ScheduleValueProps = {
 };
 
 export function ScheduleValue({ value }: ScheduleValueProps) {
-  const payees = useSelector<State, QueriesState['payees']>(
-    state => state.queries.payees,
-  );
+  const payees = usePayees();
   const byId = getPayeesById(payees);
   const { data: schedules } = SchedulesQuery.useQuery();
 
diff --git a/packages/desktop-client/src/components/rules/Value.tsx b/packages/desktop-client/src/components/rules/Value.tsx
index fe9ccc73c..d8b184b39 100644
--- a/packages/desktop-client/src/components/rules/Value.tsx
+++ b/packages/desktop-client/src/components/rules/Value.tsx
@@ -1,17 +1,16 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
-import { useSelector } from 'react-redux';
 
 import { format as formatDate, parseISO } from 'date-fns';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-import { type QueriesState } from 'loot-core/client/state-types/queries';
 import { getMonthYearFormat } from 'loot-core/src/shared/months';
 import { getRecurringDescription } from 'loot-core/src/shared/schedules';
 import { integerToCurrency } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { usePayees } from '../../hooks/usePayees';
 import { type CSSProperties, theme } from '../../style';
 import { LinkButton } from '../common/LinkButton';
 import { Text } from '../common/Text';
@@ -36,16 +35,10 @@ export function Value<T>({
   describe = x => x.name,
   style,
 }: ValueProps<T>) {
-  const dateFormat = useSelector<State, PrefsState['local']['dateFormat']>(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
-  const payees = useSelector<State, QueriesState['payees']>(
-    state => state.queries.payees,
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+  const payees = usePayees();
   const { list: categories } = useCategories();
-  const accounts = useSelector<State, QueriesState['accounts']>(
-    state => state.queries.accounts,
-  );
+  const accounts = useAccounts();
   const valueStyle = {
     color: theme.pageTextPositive,
     ...style,
diff --git a/packages/desktop-client/src/components/schedules/DiscoverSchedules.tsx b/packages/desktop-client/src/components/schedules/DiscoverSchedules.tsx
index 03a0aebaf..1f62f40c8 100644
--- a/packages/desktop-client/src/components/schedules/DiscoverSchedules.tsx
+++ b/packages/desktop-client/src/components/schedules/DiscoverSchedules.tsx
@@ -1,9 +1,6 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import { runQuery } from 'loot-core/src/client/query-helpers';
 import { send } from 'loot-core/src/platform/client/fetch';
 import { q } from 'loot-core/src/shared/query';
@@ -11,6 +8,7 @@ import { getRecurringDescription } from 'loot-core/src/shared/schedules';
 import type { DiscoverScheduleEntity } from 'loot-core/src/types/models';
 
 import type { BoundActions } from '../../hooks/useActions';
+import { useDateFormat } from '../../hooks/useDateFormat';
 import {
   useSelected,
   useSelectedDispatch,
@@ -41,9 +39,7 @@ function DiscoverSchedulesTable({
 }) {
   const selectedItems = useSelectedItems();
   const dispatchSelected = useSelectedDispatch();
-  const dateFormat = useSelector<State, PrefsState['local']['dateFormat']>(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
 
   function renderItem({ item }: { item: DiscoverScheduleEntity }) {
     const selected = selectedItems.has(item.id);
diff --git a/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx b/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
index 85446055b..56d20b442 100644
--- a/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
+++ b/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
@@ -1,14 +1,15 @@
 import React, { useEffect, useReducer } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
+import { useDispatch } from 'react-redux';
 
 import { pushModal } from 'loot-core/src/client/actions/modals';
-import { useCachedPayees } from 'loot-core/src/client/data-hooks/payees';
 import { runQuery, liveQuery } from 'loot-core/src/client/query-helpers';
 import { send, sendCatch } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import { q } from 'loot-core/src/shared/query';
 import { extractScheduleConds } from 'loot-core/src/shared/schedules';
 
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { usePayees } from '../../hooks/usePayees';
 import { useSelected, SelectedProvider } from '../../hooks/useSelected';
 import { theme } from '../../style';
 import { AccountAutocomplete } from '../autocomplete/AccountAutocomplete';
@@ -70,11 +71,10 @@ function updateScheduleConditions(schedule, fields) {
 export function ScheduleDetails({ modalProps, actions, id, transaction }) {
   const adding = id == null;
   const fromTrans = transaction != null;
-  const payees = useCachedPayees({ idKey: true });
+  const payees = usePayees({ idKey: true });
   const globalDispatch = useDispatch();
-  const dateFormat = useSelector(state => {
-    return state.prefs.local.dateFormat || 'MM/dd/yyyy';
-  });
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+
   const [state, dispatch] = useReducer(
     (state, action) => {
       switch (action.type) {
diff --git a/packages/desktop-client/src/components/schedules/SchedulesTable.tsx b/packages/desktop-client/src/components/schedules/SchedulesTable.tsx
index b2ec6ea02..ba34e2df1 100644
--- a/packages/desktop-client/src/components/schedules/SchedulesTable.tsx
+++ b/packages/desktop-client/src/components/schedules/SchedulesTable.tsx
@@ -1,11 +1,6 @@
 // @ts-strict-ignore
 import React, { useState, useMemo, type CSSProperties } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts';
-import { useCachedPayees } from 'loot-core/src/client/data-hooks/payees';
 import {
   type ScheduleStatusType,
   type ScheduleStatuses,
@@ -15,6 +10,9 @@ import { getScheduledAmount } from 'loot-core/src/shared/schedules';
 import { integerToCurrency } from 'loot-core/src/shared/util';
 import { type ScheduleEntity } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../../hooks/useAccounts';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { usePayees } from '../../hooks/usePayees';
 import { SvgDotsHorizontalTriple } from '../../icons/v1';
 import { SvgCheck } from '../../icons/v2';
 import { theme } from '../../style';
@@ -196,16 +194,11 @@ export function SchedulesTable({
   onAction,
   tableStyle,
 }: SchedulesTableProps) {
-  const dateFormat = useSelector<State, PrefsState['local']['dateFormat']>(
-    state => {
-      return state.prefs.local.dateFormat || 'MM/dd/yyyy';
-    },
-  );
-
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
   const [showCompleted, setShowCompleted] = useState(false);
 
-  const payees = useCachedPayees();
-  const accounts = useCachedAccounts();
+  const payees = usePayees();
+  const accounts = useAccounts();
 
   const filteredSchedules = useMemo(() => {
     if (!filter) {
@@ -240,7 +233,7 @@ export function SchedulesTable({
         filterIncludes(dateStr)
       );
     });
-  }, [schedules, filter, statuses]);
+  }, [payees, accounts, schedules, filter, statuses]);
 
   const items: SchedulesTableItem[] = useMemo(() => {
     const unCompletedSchedules = filteredSchedules.filter(s => !s.completed);
diff --git a/packages/desktop-client/src/components/select/DateSelect.tsx b/packages/desktop-client/src/components/select/DateSelect.tsx
index a6b83fc65..6893edc8d 100644
--- a/packages/desktop-client/src/components/select/DateSelect.tsx
+++ b/packages/desktop-client/src/components/select/DateSelect.tsx
@@ -10,15 +10,12 @@ import React, {
   type MutableRefObject,
   type KeyboardEvent,
 } from 'react';
-import { useSelector } from 'react-redux';
 
 import { parse, parseISO, format, subDays, addDays, isValid } from 'date-fns';
 import Pikaday from 'pikaday';
 
 import 'pikaday/css/pikaday.css';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import {
   getDayMonthFormat,
   getDayMonthRegex,
@@ -28,6 +25,7 @@ import {
 } from 'loot-core/src/shared/months';
 import { stringToInteger } from 'loot-core/src/shared/util';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { type CSSProperties, theme } from '../../style';
 import { Input, type InputProps } from '../common/Input';
 import { View, type ViewProps } from '../common/View';
@@ -233,14 +231,8 @@ export function DateSelect({
   const [selectedValue, setSelectedValue] = useState(value);
   const userSelectedValue = useRef(selectedValue);
 
-  const firstDayOfWeekIdx = useSelector<
-    State,
-    PrefsState['local']['firstDayOfWeekIdx']
-  >(state =>
-    state.prefs.local?.firstDayOfWeekIdx
-      ? state.prefs.local.firstDayOfWeekIdx
-      : '0',
-  );
+  const [_firstDayOfWeekIdx] = useLocalPref('firstDayOfWeekIdx');
+  const firstDayOfWeekIdx = _firstDayOfWeekIdx || '0';
 
   useEffect(() => {
     userSelectedValue.current = value;
diff --git a/packages/desktop-client/src/components/select/RecurringSchedulePicker.jsx b/packages/desktop-client/src/components/select/RecurringSchedulePicker.jsx
index df1023716..17ee82e87 100644
--- a/packages/desktop-client/src/components/select/RecurringSchedulePicker.jsx
+++ b/packages/desktop-client/src/components/select/RecurringSchedulePicker.jsx
@@ -1,10 +1,10 @@
 import React, { useEffect, useReducer, useState } from 'react';
-import { useSelector } from 'react-redux';
 
 import { sendCatch } from 'loot-core/src/platform/client/fetch';
 import * as monthUtils from 'loot-core/src/shared/months';
 import { getRecurringDescription } from 'loot-core/src/shared/schedules';
 
+import { useDateFormat } from '../../hooks/useDateFormat';
 import { SvgAdd, SvgSubtract } from '../../icons/v0';
 import { theme } from '../../style';
 import { Button } from '../common/Button';
@@ -159,11 +159,9 @@ function reducer(state, action) {
 }
 
 function SchedulePreview({ previewDates }) {
-  const dateFormat = useSelector(state =>
-    (state.prefs.local.dateFormat || 'MM/dd/yyyy')
-      .replace('MM', 'M')
-      .replace('dd', 'd'),
-  );
+  const dateFormat = (useDateFormat() || 'MM/dd/yyyy')
+    .replace('MM', 'M')
+    .replace('dd', 'd');
 
   if (!previewDates) {
     return null;
@@ -281,9 +279,7 @@ function RecurringScheduleTooltip({ config: currentConfig, onClose, onSave }) {
   const skipWeekend = state.config.hasOwnProperty('skipWeekend')
     ? state.config.skipWeekend
     : false;
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
 
   useEffect(() => {
     dispatch({
@@ -481,9 +477,7 @@ function RecurringScheduleTooltip({ config: currentConfig, onClose, onSave }) {
 
 export function RecurringSchedulePicker({ value, buttonStyle, onChange }) {
   const { isOpen, close, getOpenEvents } = useTooltip();
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
 
   function onSave(config) {
     onChange(config);
diff --git a/packages/desktop-client/src/components/settings/Encryption.tsx b/packages/desktop-client/src/components/settings/Encryption.tsx
index cfe994b13..97a7660ce 100644
--- a/packages/desktop-client/src/components/settings/Encryption.tsx
+++ b/packages/desktop-client/src/components/settings/Encryption.tsx
@@ -1,11 +1,8 @@
 // @ts-strict-ignore
 import React from 'react';
-import { useSelector } from 'react-redux';
-
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 
 import { useActions } from '../../hooks/useActions';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { theme } from '../../style';
 import { Button } from '../common/Button';
 import { ExternalLink } from '../common/ExternalLink';
@@ -17,9 +14,7 @@ import { Setting } from './UI';
 export function EncryptionSettings() {
   const { pushModal } = useActions();
   const serverURL = useServerURL();
-  const encryptKeyId = useSelector<State, PrefsState['local']['encryptKeyId']>(
-    state => state.prefs.local.encryptKeyId,
-  );
+  const [encryptKeyId] = useLocalPref('encryptKeyId');
 
   const missingCryptoAPI = !(window.crypto && crypto.subtle);
 
diff --git a/packages/desktop-client/src/components/settings/Experimental.tsx b/packages/desktop-client/src/components/settings/Experimental.tsx
index fc1a942c5..15f20989f 100644
--- a/packages/desktop-client/src/components/settings/Experimental.tsx
+++ b/packages/desktop-client/src/components/settings/Experimental.tsx
@@ -1,12 +1,9 @@
 import { type ReactNode, useState } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/src/client/state-types';
-import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
 import type { FeatureFlag } from 'loot-core/src/types/prefs';
 
-import { useActions } from '../../hooks/useActions';
 import { useFeatureFlag } from '../../hooks/useFeatureFlag';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { theme } from '../../style';
 import { LinkButton } from '../common/LinkButton';
 import { Text } from '../common/Text';
@@ -23,23 +20,20 @@ type FeatureToggleProps = {
 };
 
 function FeatureToggle({
-  flag,
+  flag: flagName,
   disableToggle = false,
   error,
   children,
 }: FeatureToggleProps) {
-  const { savePrefs } = useActions();
-  const enabled = useFeatureFlag(flag);
+  const enabled = useFeatureFlag(flagName);
+  const [_, setFlagPref] = useLocalPref(`flags.${flagName}`);
 
   return (
     <label style={{ display: 'flex' }}>
       <Checkbox
         checked={enabled}
         onChange={() => {
-          // @ts-expect-error key type is not correctly inferred
-          savePrefs({
-            [`flags.${flag}`]: !enabled,
-          });
+          setFlagPref(!enabled);
         }}
         disabled={disableToggle}
       />
@@ -63,9 +57,7 @@ function FeatureToggle({
 }
 
 function ReportBudgetFeature() {
-  const budgetType = useSelector<State, PrefsState['local']['budgetType']>(
-    state => state.prefs.local?.budgetType,
-  );
+  const [budgetType] = useLocalPref('budgetType');
   const enabled = useFeatureFlag('reportBudget');
   const blockToggleOff = budgetType === 'report' && enabled;
   return (
diff --git a/packages/desktop-client/src/components/settings/Export.tsx b/packages/desktop-client/src/components/settings/Export.tsx
index 6cd2e7449..824c0f4fa 100644
--- a/packages/desktop-client/src/components/settings/Export.tsx
+++ b/packages/desktop-client/src/components/settings/Export.tsx
@@ -1,13 +1,11 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
-import { useSelector } from 'react-redux';
 
 import { format } from 'date-fns';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import { send } from 'loot-core/src/platform/client/fetch';
 
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { theme } from '../../style';
 import { Block } from '../common/Block';
 import { ButtonWithLoading } from '../common/Button';
@@ -18,12 +16,8 @@ import { Setting } from './UI';
 export function ExportBudget() {
   const [isLoading, setIsLoading] = useState(false);
   const [error, setError] = useState<string | null>(null);
-  const budgetId = useSelector<State, PrefsState['local']['id']>(
-    state => state.prefs.local.id,
-  );
-  const encryptKeyId = useSelector<State, PrefsState['local']['encryptKeyId']>(
-    state => state.prefs.local.encryptKeyId,
-  );
+  const [budgetId] = useLocalPref('id');
+  const [encryptKeyId] = useLocalPref('encryptKeyId');
 
   async function onExport() {
     setIsLoading(true);
diff --git a/packages/desktop-client/src/components/settings/Format.tsx b/packages/desktop-client/src/components/settings/Format.tsx
index 8f36cc434..0dc2fbf03 100644
--- a/packages/desktop-client/src/components/settings/Format.tsx
+++ b/packages/desktop-client/src/components/settings/Format.tsx
@@ -1,20 +1,18 @@
 // @ts-strict-ignore
 import React, { type ReactNode } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import { numberFormats } from 'loot-core/src/shared/util';
 import { type LocalPrefs } from 'loot-core/src/types/prefs';
 
-import { useActions } from '../../hooks/useActions';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { tokens } from '../../tokens';
 import { Button } from '../common/Button';
 import { Select } from '../common/Select';
 import { Text } from '../common/Text';
 import { View } from '../common/View';
 import { Checkbox } from '../forms';
-import { useSidebar } from '../sidebar';
+import { useSidebar } from '../sidebar/SidebarProvider';
 
 import { Setting } from './UI';
 
@@ -56,24 +54,16 @@ function Column({ title, children }: { title: string; children: ReactNode }) {
 }
 
 export function FormatSettings() {
-  const { savePrefs } = useActions();
-
   const sidebar = useSidebar();
-  const firstDayOfWeekIdx = useSelector<
-    State,
-    PrefsState['local']['firstDayOfWeekIdx']
-  >(
-    state => state.prefs.local.firstDayOfWeekIdx || '0', // Sunday
-  );
-  const dateFormat = useSelector<State, PrefsState['local']['dateFormat']>(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
-  const numberFormat = useSelector<State, PrefsState['local']['numberFormat']>(
-    state => state.prefs.local.numberFormat || 'comma-dot',
-  );
-  const hideFraction = useSelector<State, PrefsState['local']['hideFraction']>(
-    state => state.prefs.local.hideFraction,
-  );
+  const [_firstDayOfWeekIdx, setFirstDayOfWeekIdxPref] =
+    useLocalPref('firstDayOfWeekIdx'); // Sunday;
+  const firstDayOfWeekIdx = _firstDayOfWeekIdx || '0';
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
+  const [, setDateFormatPref] = useLocalPref('dateFormat');
+  const [_numberFormat, setNumberFormatPref] = useLocalPref('numberFormat');
+  const numberFormat = _numberFormat || 'comma-dot';
+  const [hideFraction = false, setHideFractionPref] =
+    useLocalPref('hideFraction');
 
   return (
     <Setting
@@ -98,7 +88,7 @@ export function FormatSettings() {
                 bare
                 key={String(hideFraction)} // needed because label does not update
                 value={numberFormat}
-                onChange={format => savePrefs({ numberFormat: format })}
+                onChange={format => setNumberFormatPref(format)}
                 options={numberFormats.map(f => [
                   f.value,
                   hideFraction ? f.labelNoFraction : f.label,
@@ -111,9 +101,7 @@ export function FormatSettings() {
               <Checkbox
                 id="settings-textDecimal"
                 checked={!!hideFraction}
-                onChange={e =>
-                  savePrefs({ hideFraction: e.currentTarget.checked })
-                }
+                onChange={e => setHideFractionPref(e.currentTarget.checked)}
               />
               <label htmlFor="settings-textDecimal">Hide decimal places</label>
             </Text>
@@ -124,7 +112,7 @@ export function FormatSettings() {
               <Select
                 bare
                 value={dateFormat}
-                onChange={format => savePrefs({ dateFormat: format })}
+                onChange={format => setDateFormatPref(format)}
                 options={dateFormats.map(f => [f.value, f.label])}
                 style={{ padding: '2px 10px', fontSize: 15 }}
               />
@@ -136,7 +124,7 @@ export function FormatSettings() {
               <Select
                 bare
                 value={firstDayOfWeekIdx}
-                onChange={idx => savePrefs({ firstDayOfWeekIdx: idx })}
+                onChange={idx => setFirstDayOfWeekIdxPref(idx)}
                 options={daysOfWeek.map(f => [f.value, f.label])}
                 style={{ padding: '2px 10px', fontSize: 15 }}
               />
diff --git a/packages/desktop-client/src/components/settings/Global.tsx b/packages/desktop-client/src/components/settings/Global.tsx
index aad153e5e..92e4ba843 100644
--- a/packages/desktop-client/src/components/settings/Global.tsx
+++ b/packages/desktop-client/src/components/settings/Global.tsx
@@ -1,11 +1,7 @@
 // @ts-strict-ignore
 import React, { useState, useEffect, useRef } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-
-import { useActions } from '../../hooks/useActions';
+import { useGlobalPref } from '../../hooks/useGlobalPref';
 import { theme } from '../../style';
 import { Information } from '../alerts';
 import { Button } from '../common/Button';
@@ -15,10 +11,7 @@ import { View } from '../common/View';
 import { Setting } from './UI';
 
 export function GlobalSettings() {
-  const documentDir = useSelector<State, PrefsState['global']['documentDir']>(
-    state => state.prefs.global.documentDir,
-  );
-  const { saveGlobalPrefs } = useActions();
+  const [documentDir, setDocumentDirPref] = useGlobalPref('documentDir');
 
   const [documentDirChanged, setDirChanged] = useState(false);
   const dirScrolled = useRef<HTMLSpanElement>(null);
@@ -34,7 +27,7 @@ export function GlobalSettings() {
       properties: ['openDirectory'],
     });
     if (res) {
-      saveGlobalPrefs({ documentDir: res[0] });
+      setDocumentDirPref(res[0]);
       setDirChanged(true);
     }
   }
diff --git a/packages/desktop-client/src/components/settings/Reset.tsx b/packages/desktop-client/src/components/settings/Reset.tsx
index 744ada38e..0e8ea3cea 100644
--- a/packages/desktop-client/src/components/settings/Reset.tsx
+++ b/packages/desktop-client/src/components/settings/Reset.tsx
@@ -1,12 +1,10 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import { send } from 'loot-core/src/platform/client/fetch';
 
 import { useActions } from '../../hooks/useActions';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { ButtonWithLoading } from '../common/Button';
 import { Text } from '../common/Text';
 
@@ -41,9 +39,8 @@ export function ResetCache() {
 }
 
 export function ResetSync() {
-  const isEnabled = !!useSelector<State, PrefsState['local']['groupId']>(
-    state => state.prefs.local.groupId,
-  );
+  const [groupId] = useLocalPref('groupId');
+  const isEnabled = !!groupId;
   const { resetSync } = useActions();
 
   const [resetting, setResetting] = useState(false);
diff --git a/packages/desktop-client/src/components/settings/Themes.tsx b/packages/desktop-client/src/components/settings/Themes.tsx
index 775ef5253..7966b546a 100644
--- a/packages/desktop-client/src/components/settings/Themes.tsx
+++ b/packages/desktop-client/src/components/settings/Themes.tsx
@@ -1,6 +1,7 @@
 import React from 'react';
 
-import { useActions } from '../../hooks/useActions';
+import { type Theme } from 'loot-core/types/prefs';
+
 import { themeOptions, useTheme } from '../../style';
 import { Button } from '../common/Button';
 import { Select } from '../common/Select';
@@ -9,17 +10,16 @@ import { Text } from '../common/Text';
 import { Setting } from './UI';
 
 export function ThemeSettings() {
-  const theme = useTheme();
-  const { saveGlobalPrefs } = useActions();
+  const [theme, switchTheme] = useTheme();
 
   return (
     <Setting
       primaryAction={
         <Button bounce={false} style={{ padding: 0 }}>
-          <Select
+          <Select<Theme>
             bare
             onChange={value => {
-              saveGlobalPrefs({ theme: value });
+              switchTheme(value);
             }}
             value={theme}
             options={themeOptions}
diff --git a/packages/desktop-client/src/components/settings/index.tsx b/packages/desktop-client/src/components/settings/index.tsx
index 454f41575..2f7ef5ada 100644
--- a/packages/desktop-client/src/components/settings/index.tsx
+++ b/packages/desktop-client/src/components/settings/index.tsx
@@ -1,16 +1,15 @@
 // @ts-strict-ignore
 import React, { type ReactNode, useEffect } from 'react';
-import { useSelector } from 'react-redux';
 
 import { media } from 'glamor';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import * as Platform from 'loot-core/src/client/platform';
 import { listen } from 'loot-core/src/platform/client/fetch';
 
 import { useActions } from '../../hooks/useActions';
+import { useGlobalPref } from '../../hooks/useGlobalPref';
 import { useLatestVersion, useIsOutdated } from '../../hooks/useLatestVersion';
+import { useLocalPref } from '../../hooks/useLocalPref';
 import { useSetThemeColor } from '../../hooks/useSetThemeColor';
 import { useResponsive } from '../../ResponsiveProvider';
 import { theme } from '../../style';
@@ -91,12 +90,8 @@ function IDName({ children }: { children: ReactNode }) {
 }
 
 function AdvancedAbout() {
-  const budgetId = useSelector<State, PrefsState['local']['id']>(
-    state => state.prefs.local.id,
-  );
-  const groupId = useSelector<State, PrefsState['local']['groupId']>(
-    state => state.prefs.local.groupId,
-  );
+  const [budgetId] = useLocalPref('id');
+  const [groupId] = useLocalPref('groupId');
 
   return (
     <Setting>
@@ -124,13 +119,8 @@ function AdvancedAbout() {
 }
 
 export function Settings() {
-  const floatingSidebar = useSelector<
-    State,
-    PrefsState['global']['floatingSidebar']
-  >(state => state.prefs.global.floatingSidebar);
-  const budgetName = useSelector<State, PrefsState['local']['budgetName']>(
-    state => state.prefs.local.budgetName,
-  );
+  const [floatingSidebar] = useGlobalPref('floatingSidebar');
+  const [budgetName] = useLocalPref('budgetName');
 
   const { loadPrefs, closeBudget } = useActions();
 
diff --git a/packages/desktop-client/src/components/sidebar/Accounts.tsx b/packages/desktop-client/src/components/sidebar/Accounts.tsx
index cd20ccb58..e85e32e4a 100644
--- a/packages/desktop-client/src/components/sidebar/Accounts.tsx
+++ b/packages/desktop-client/src/components/sidebar/Accounts.tsx
@@ -1,12 +1,17 @@
 // @ts-strict-ignore
-import React, { useState, useMemo } from 'react';
+import React, { useState } from 'react';
 
-import { type AccountEntity } from 'loot-core/src/types/models';
+import * as queries from 'loot-core/src/client/queries';
 
+import { useBudgetedAccounts } from '../../hooks/useBudgetedAccounts';
+import { useClosedAccounts } from '../../hooks/useClosedAccounts';
+import { useFailedAccounts } from '../../hooks/useFailedAccounts';
+import { useLocalPref } from '../../hooks/useLocalPref';
+import { useOffBudgetAccounts } from '../../hooks/useOffBudgetAccounts';
+import { useUpdatedAccounts } from '../../hooks/useUpdatedAccounts';
 import { SvgAdd } from '../../icons/v1';
 import { View } from '../common/View';
 import { type OnDropCallback } from '../sort';
-import { type Binding } from '../spreadsheet';
 
 import { Account } from './Account';
 import { SecondaryItem } from './SecondaryItem';
@@ -14,65 +19,26 @@ import { SecondaryItem } from './SecondaryItem';
 const fontWeight = 600;
 
 type AccountsProps = {
-  accounts: AccountEntity[];
-  failedAccounts: Map<
-    string,
-    {
-      type: string;
-      code: string;
-    }
-  >;
-  updatedAccounts: string[];
-  getAccountPath: (account: AccountEntity) => string;
-  allAccountsPath: string;
-  budgetedAccountPath: string;
-  offBudgetAccountPath: string;
-  getBalanceQuery: (account: AccountEntity) => Binding;
-  getAllAccountBalance: () => Binding;
-  getOnBudgetBalance: () => Binding;
-  getOffBudgetBalance: () => Binding;
-  showClosedAccounts: boolean;
   onAddAccount: () => void;
   onToggleClosedAccounts: () => void;
   onReorder: OnDropCallback;
 };
 
 export function Accounts({
-  accounts,
-  failedAccounts,
-  updatedAccounts,
-  getAccountPath,
-  allAccountsPath,
-  budgetedAccountPath,
-  offBudgetAccountPath,
-  getBalanceQuery,
-  getAllAccountBalance,
-  getOnBudgetBalance,
-  getOffBudgetBalance,
-  showClosedAccounts,
   onAddAccount,
   onToggleClosedAccounts,
   onReorder,
 }: AccountsProps) {
   const [isDragging, setIsDragging] = useState(false);
-  const offbudgetAccounts = useMemo(
-    () =>
-      accounts.filter(
-        account => account.closed === 0 && account.offbudget === 1,
-      ),
-    [accounts],
-  );
-  const budgetedAccounts = useMemo(
-    () =>
-      accounts.filter(
-        account => account.closed === 0 && account.offbudget === 0,
-      ),
-    [accounts],
-  );
-  const closedAccounts = useMemo(
-    () => accounts.filter(account => account.closed === 1),
-    [accounts],
-  );
+  const failedAccounts = useFailedAccounts();
+  const updatedAccounts = useUpdatedAccounts();
+  const offbudgetAccounts = useOffBudgetAccounts();
+  const budgetedAccounts = useBudgetedAccounts();
+  const closedAccounts = useClosedAccounts();
+
+  const getAccountPath = account => `/accounts/${account.id}`;
+
+  const [showClosedAccounts] = useLocalPref('ui.showClosedAccounts');
 
   function onDragChange(drag) {
     setIsDragging(drag.state === 'start');
@@ -92,16 +58,16 @@ export function Accounts({
     <View>
       <Account
         name="All accounts"
-        to={allAccountsPath}
-        query={getAllAccountBalance()}
+        to="/accounts"
+        query={queries.allAccountBalance()}
         style={{ fontWeight, marginTop: 15 }}
       />
 
       {budgetedAccounts.length > 0 && (
         <Account
           name="For budget"
-          to={budgetedAccountPath}
-          query={getOnBudgetBalance()}
+          to="/accounts/budgeted"
+          query={queries.budgetedAccountBalance()}
           style={{ fontWeight, marginTop: 13 }}
         />
       )}
@@ -115,7 +81,7 @@ export function Accounts({
           failed={failedAccounts && failedAccounts.has(account.id)}
           updated={updatedAccounts && updatedAccounts.includes(account.id)}
           to={getAccountPath(account)}
-          query={getBalanceQuery(account)}
+          query={queries.accountBalance(account)}
           onDragChange={onDragChange}
           onDrop={onReorder}
           outerStyle={makeDropPadding(i)}
@@ -125,8 +91,8 @@ export function Accounts({
       {offbudgetAccounts.length > 0 && (
         <Account
           name="Off budget"
-          to={offBudgetAccountPath}
-          query={getOffBudgetBalance()}
+          to="/accounts/offbudget"
+          query={queries.offbudgetAccountBalance()}
           style={{ fontWeight, marginTop: 13 }}
         />
       )}
@@ -140,7 +106,7 @@ export function Accounts({
           failed={failedAccounts && failedAccounts.has(account.id)}
           updated={updatedAccounts && updatedAccounts.includes(account.id)}
           to={getAccountPath(account)}
-          query={getBalanceQuery(account)}
+          query={queries.accountBalance(account)}
           onDragChange={onDragChange}
           onDrop={onReorder}
           outerStyle={makeDropPadding(i)}
@@ -163,7 +129,7 @@ export function Accounts({
             name={account.name}
             account={account}
             to={getAccountPath(account)}
-            query={getBalanceQuery(account)}
+            query={queries.accountBalance(account)}
             onDragChange={onDragChange}
             onDrop={onReorder}
           />
diff --git a/packages/desktop-client/src/components/sidebar/Sidebar.tsx b/packages/desktop-client/src/components/sidebar/Sidebar.tsx
index dadd3ba95..b8d59bbde 100644
--- a/packages/desktop-client/src/components/sidebar/Sidebar.tsx
+++ b/packages/desktop-client/src/components/sidebar/Sidebar.tsx
@@ -1,68 +1,74 @@
-import React, { type ReactNode } from 'react';
-
+import React, { useState } from 'react';
+import { useDispatch } from 'react-redux';
+
+import {
+  closeBudget,
+  moveAccount,
+  replaceModal,
+} from 'loot-core/src/client/actions';
 import * as Platform from 'loot-core/src/client/platform';
-import { type AccountEntity } from 'loot-core/src/types/models';
 
+import { useAccounts } from '../../hooks/useAccounts';
+import { useGlobalPref } from '../../hooks/useGlobalPref';
+import { useLocalPref } from '../../hooks/useLocalPref';
+import { useNavigate } from '../../hooks/useNavigate';
+import { SvgExpandArrow } from '../../icons/v0';
 import { SvgReports, SvgWallet } from '../../icons/v1';
 import { SvgCalendar } from '../../icons/v2';
-import { type CSSProperties, theme } from '../../style';
+import { styles, theme } from '../../style';
+import { Button } from '../common/Button';
+import { InitialFocus } from '../common/InitialFocus';
+import { Input } from '../common/Input';
+import { Menu } from '../common/Menu';
+import { Text } from '../common/Text';
 import { View } from '../common/View';
-import { type OnDropCallback } from '../sort';
-import { type Binding } from '../spreadsheet';
+import { Tooltip } from '../tooltips';
 
 import { Accounts } from './Accounts';
 import { Item } from './Item';
+import { useSidebar } from './SidebarProvider';
 import { ToggleButton } from './ToggleButton';
 import { Tools } from './Tools';
 
-import { useSidebar } from '.';
-
 export const SIDEBAR_WIDTH = 240;
 
-type SidebarProps = {
-  style: CSSProperties;
-  budgetName: ReactNode;
-  accounts: AccountEntity[];
-  failedAccounts: Map<
-    string,
-    {
-      type: string;
-      code: string;
-    }
-  >;
-  updatedAccounts: string[];
-  getBalanceQuery: (account: AccountEntity) => Binding;
-  getAllAccountBalance: () => Binding;
-  getOnBudgetBalance: () => Binding;
-  getOffBudgetBalance: () => Binding;
-  showClosedAccounts: boolean;
-  isFloating: boolean;
-  onFloat: () => void;
-  onAddAccount: () => void;
-  onToggleClosedAccounts: () => void;
-  onReorder: OnDropCallback;
-};
-
-export function Sidebar({
-  style,
-  budgetName,
-  accounts,
-  failedAccounts,
-  updatedAccounts,
-  getBalanceQuery,
-  getAllAccountBalance,
-  getOnBudgetBalance,
-  getOffBudgetBalance,
-  showClosedAccounts,
-  isFloating,
-  onFloat,
-  onAddAccount,
-  onToggleClosedAccounts,
-  onReorder,
-}: SidebarProps) {
+export function Sidebar() {
   const hasWindowButtons = !Platform.isBrowser && Platform.OS === 'mac';
 
+  const dispatch = useDispatch();
   const sidebar = useSidebar();
+  const accounts = useAccounts();
+  const [showClosedAccounts, setShowClosedAccountsPref] = useLocalPref(
+    'ui.showClosedAccounts',
+  );
+  const [isFloating = false, setFloatingSidebarPref] =
+    useGlobalPref('floatingSidebar');
+
+  async function onReorder(
+    id: string,
+    dropPos: 'top' | 'bottom',
+    targetId: unknown,
+  ) {
+    let targetIdToMove = targetId;
+    if (dropPos === 'bottom') {
+      const idx = accounts.findIndex(a => a.id === targetId) + 1;
+      targetIdToMove = idx < accounts.length ? accounts[idx].id : null;
+    }
+
+    dispatch(moveAccount(id, targetIdToMove));
+  }
+
+  const onFloat = () => {
+    setFloatingSidebarPref(!isFloating);
+  };
+
+  const onAddAccount = () => {
+    dispatch(replaceModal('add-account'));
+  };
+
+  const onToggleClosedAccounts = () => {
+    setShowClosedAccountsPref(!showClosedAccounts);
+  };
 
   return (
     <View
@@ -79,7 +85,8 @@ export function Sidebar({
           opacity: 1,
           width: hasWindowButtons ? null : 'auto',
         },
-        ...style,
+        flex: 1,
+        ...styles.darkScrollbar,
       }}
     >
       <View
@@ -96,7 +103,7 @@ export function Sidebar({
           }),
         }}
       >
-        {budgetName}
+        <EditableBudgetName />
 
         <View style={{ flex: 1, flexDirection: 'row' }} />
 
@@ -123,18 +130,6 @@ export function Sidebar({
         />
 
         <Accounts
-          accounts={accounts}
-          failedAccounts={failedAccounts}
-          updatedAccounts={updatedAccounts}
-          getAccountPath={account => `/accounts/${account.id}`}
-          allAccountsPath="/accounts"
-          budgetedAccountPath="/accounts/budgeted"
-          offBudgetAccountPath="/accounts/offbudget"
-          getBalanceQuery={getBalanceQuery}
-          getAllAccountBalance={getAllAccountBalance}
-          getOnBudgetBalance={getOnBudgetBalance}
-          getOffBudgetBalance={getOffBudgetBalance}
-          showClosedAccounts={showClosedAccounts}
           onAddAccount={onAddAccount}
           onToggleClosedAccounts={onToggleClosedAccounts}
           onReorder={onReorder}
@@ -143,3 +138,90 @@ export function Sidebar({
     </View>
   );
 }
+
+function EditableBudgetName() {
+  const dispatch = useDispatch();
+  const navigate = useNavigate();
+  const [budgetName, setBudgetNamePref] = useLocalPref('budgetName');
+  const [editing, setEditing] = useState(false);
+  const [menuOpen, setMenuOpen] = useState(false);
+
+  function onMenuSelect(type: string) {
+    setMenuOpen(false);
+
+    switch (type) {
+      case 'rename':
+        setEditing(true);
+        break;
+      case 'settings':
+        navigate('/settings');
+        break;
+      case 'help':
+        window.open('https://actualbudget.org/docs/', '_blank');
+        break;
+      case 'close':
+        dispatch(closeBudget());
+        break;
+      default:
+    }
+  }
+
+  const items = [
+    { name: 'rename', text: 'Rename budget' },
+    { name: 'settings', text: 'Settings' },
+    ...(Platform.isBrowser ? [{ name: 'help', text: 'Help' }] : []),
+    { name: 'close', text: 'Close file' },
+  ];
+
+  if (editing) {
+    return (
+      <InitialFocus>
+        <Input
+          style={{
+            width: 160,
+            fontSize: 16,
+            fontWeight: 500,
+          }}
+          defaultValue={budgetName}
+          onEnter={async e => {
+            const inputEl = e.target as HTMLInputElement;
+            const newBudgetName = inputEl.value;
+            if (newBudgetName.trim() !== '') {
+              setBudgetNamePref(inputEl.name);
+              setEditing(false);
+            }
+          }}
+          onBlur={() => setEditing(false)}
+        />
+      </InitialFocus>
+    );
+  } else {
+    return (
+      <Button
+        type="bare"
+        color={theme.buttonNormalBorder}
+        style={{
+          fontSize: 16,
+          fontWeight: 500,
+          marginLeft: -5,
+          flex: '0 auto',
+        }}
+        onClick={() => setMenuOpen(true)}
+      >
+        <Text style={{ whiteSpace: 'nowrap', overflow: 'hidden' }}>
+          {budgetName || 'A budget has no name'}
+        </Text>
+        <SvgExpandArrow width={7} height={7} style={{ marginLeft: 5 }} />
+        {menuOpen && (
+          <Tooltip
+            position="bottom-left"
+            style={{ padding: 0 }}
+            onClose={() => setMenuOpen(false)}
+          >
+            <Menu onMenuSelect={onMenuSelect} items={items} />
+          </Tooltip>
+        )}
+      </Button>
+    );
+  }
+}
diff --git a/packages/desktop-client/src/components/sidebar/SidebarProvider.tsx b/packages/desktop-client/src/components/sidebar/SidebarProvider.tsx
new file mode 100644
index 000000000..717f3393e
--- /dev/null
+++ b/packages/desktop-client/src/components/sidebar/SidebarProvider.tsx
@@ -0,0 +1,52 @@
+// @ts-strict-ignore
+import React, {
+  createContext,
+  useState,
+  useContext,
+  useMemo,
+  type ReactNode,
+  type Dispatch,
+  type SetStateAction,
+} from 'react';
+
+import { useGlobalPref } from '../../hooks/useGlobalPref';
+import { useResponsive } from '../../ResponsiveProvider';
+
+type SidebarContextValue = {
+  hidden: boolean;
+  setHidden: Dispatch<SetStateAction<boolean>>;
+  floating: boolean;
+  alwaysFloats: boolean;
+};
+
+const SidebarContext = createContext<SidebarContextValue>(null);
+
+type SidebarProviderProps = {
+  children: ReactNode;
+};
+
+export function SidebarProvider({ children }: SidebarProviderProps) {
+  const [floatingSidebar] = useGlobalPref('floatingSidebar');
+  const [hidden, setHidden] = useState(true);
+  const { width } = useResponsive();
+  const alwaysFloats = width < 668;
+  const floating = floatingSidebar || alwaysFloats;
+
+  return (
+    <SidebarContext.Provider
+      value={{ hidden, setHidden, floating, alwaysFloats }}
+    >
+      {children}
+    </SidebarContext.Provider>
+  );
+}
+
+export function useSidebar() {
+  const { hidden, setHidden, floating, alwaysFloats } =
+    useContext(SidebarContext);
+
+  return useMemo(
+    () => ({ hidden, setHidden, floating, alwaysFloats }),
+    [hidden, setHidden, floating, alwaysFloats],
+  );
+}
diff --git a/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx b/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx
deleted file mode 100644
index 202e84bfe..000000000
--- a/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx
+++ /dev/null
@@ -1,181 +0,0 @@
-// @ts-strict-ignore
-import React, { useState, useEffect } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-
-import { type State } from 'loot-core/client/state-types';
-import { type AccountState } from 'loot-core/client/state-types/account';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
-import { type QueriesState } from 'loot-core/client/state-types/queries';
-import { closeBudget } from 'loot-core/src/client/actions/budgets';
-import * as Platform from 'loot-core/src/client/platform';
-import * as queries from 'loot-core/src/client/queries';
-import { send } from 'loot-core/src/platform/client/fetch';
-import { type LocalPrefs } from 'loot-core/src/types/prefs';
-
-import { useActions } from '../../hooks/useActions';
-import { useNavigate } from '../../hooks/useNavigate';
-import { SvgExpandArrow } from '../../icons/v0';
-import { styles, theme } from '../../style';
-import { Button } from '../common/Button';
-import { InitialFocus } from '../common/InitialFocus';
-import { Input } from '../common/Input';
-import { Menu } from '../common/Menu';
-import { Text } from '../common/Text';
-import { Tooltip } from '../tooltips';
-
-import { Sidebar } from './Sidebar';
-
-type EditableBudgetNameProps = {
-  prefs: LocalPrefs;
-  savePrefs: (prefs: Partial<LocalPrefs>) => Promise<void>;
-};
-
-function EditableBudgetName({ prefs, savePrefs }: EditableBudgetNameProps) {
-  const dispatch = useDispatch();
-  const navigate = useNavigate();
-  const [editing, setEditing] = useState(false);
-  const [menuOpen, setMenuOpen] = useState(false);
-
-  function onMenuSelect(type) {
-    setMenuOpen(false);
-
-    switch (type) {
-      case 'rename':
-        setEditing(true);
-        break;
-      case 'settings':
-        navigate('/settings');
-        break;
-      case 'help':
-        window.open('https://actualbudget.org/docs/', '_blank');
-        break;
-      case 'close':
-        dispatch(closeBudget());
-        break;
-      default:
-    }
-  }
-
-  const items = [
-    { name: 'rename', text: 'Rename budget' },
-    { name: 'settings', text: 'Settings' },
-    ...(Platform.isBrowser ? [{ name: 'help', text: 'Help' }] : []),
-    { name: 'close', text: 'Close file' },
-  ];
-
-  const onSaveChanges = async e => {
-    const inputEl = e.target;
-    const newBudgetName = inputEl.value;
-    if (newBudgetName.trim() !== '') {
-      await savePrefs({
-        budgetName: inputEl.value,
-      });
-      setEditing(false);
-    }
-  };
-
-  if (editing) {
-    return (
-      <InitialFocus>
-        <Input
-          style={{
-            width: 160,
-            fontSize: 16,
-            fontWeight: 500,
-          }}
-          defaultValue={prefs.budgetName}
-          onEnter={onSaveChanges}
-          onBlur={onSaveChanges}
-          onEscape={() => setEditing(false)}
-        />
-      </InitialFocus>
-    );
-  } else {
-    return (
-      <Button
-        type="bare"
-        color={theme.buttonNormalBorder}
-        style={{
-          fontSize: 16,
-          fontWeight: 500,
-          marginLeft: -5,
-          flex: '0 auto',
-        }}
-        onClick={() => setMenuOpen(true)}
-      >
-        <Text style={{ whiteSpace: 'nowrap', overflow: 'hidden' }}>
-          {prefs.budgetName || 'A budget has no name'}
-        </Text>
-        <SvgExpandArrow width={7} height={7} style={{ marginLeft: 5 }} />
-        {menuOpen && (
-          <Tooltip
-            position="bottom-left"
-            style={{ padding: 0 }}
-            onClose={() => setMenuOpen(false)}
-          >
-            <Menu onMenuSelect={onMenuSelect} items={items} />
-          </Tooltip>
-        )}
-      </Button>
-    );
-  }
-}
-
-export function SidebarWithData() {
-  const accounts = useSelector<State, QueriesState['accounts']>(
-    state => state.queries.accounts,
-  );
-  const failedAccounts = useSelector<State, AccountState['failedAccounts']>(
-    state => state.account.failedAccounts,
-  );
-  const updatedAccounts = useSelector<State, QueriesState['updatedAccounts']>(
-    state => state.queries.updatedAccounts,
-  );
-  const prefs = useSelector<State, LocalPrefs>(state => state.prefs.local);
-  const floatingSidebar = useSelector<
-    State,
-    PrefsState['global']['floatingSidebar']
-  >(state => state.prefs.global.floatingSidebar);
-
-  const { getAccounts, replaceModal, savePrefs, saveGlobalPrefs } =
-    useActions();
-
-  useEffect(() => void getAccounts(), [getAccounts]);
-
-  async function onReorder(id, dropPos, targetId) {
-    if (dropPos === 'bottom') {
-      const idx = accounts.findIndex(a => a.id === targetId) + 1;
-      targetId = idx < accounts.length ? accounts[idx].id : null;
-    }
-
-    await send('account-move', { id, targetId });
-    await getAccounts();
-  }
-
-  return (
-    <Sidebar
-      budgetName={<EditableBudgetName prefs={prefs} savePrefs={savePrefs} />}
-      isFloating={floatingSidebar}
-      accounts={accounts}
-      failedAccounts={failedAccounts}
-      updatedAccounts={updatedAccounts}
-      getBalanceQuery={queries.accountBalance}
-      getAllAccountBalance={queries.allAccountBalance}
-      getOnBudgetBalance={queries.budgetedAccountBalance}
-      getOffBudgetBalance={queries.offbudgetAccountBalance}
-      onFloat={() => saveGlobalPrefs({ floatingSidebar: !floatingSidebar })}
-      onReorder={onReorder}
-      onAddAccount={() => replaceModal('add-account')}
-      showClosedAccounts={prefs['ui.showClosedAccounts']}
-      onToggleClosedAccounts={() =>
-        savePrefs({
-          'ui.showClosedAccounts': !prefs['ui.showClosedAccounts'],
-        })
-      }
-      style={{
-        flex: 1,
-        ...styles.darkScrollbar,
-      }}
-    />
-  );
-}
diff --git a/packages/desktop-client/src/components/sidebar/index.tsx b/packages/desktop-client/src/components/sidebar/index.tsx
index c3f02e448..59f7b1628 100644
--- a/packages/desktop-client/src/components/sidebar/index.tsx
+++ b/packages/desktop-client/src/components/sidebar/index.tsx
@@ -1,71 +1,14 @@
-// @ts-strict-ignore
-import React, {
-  createContext,
-  useState,
-  useContext,
-  useMemo,
-  type ReactNode,
-  type Dispatch,
-  type SetStateAction,
-} from 'react';
-import { useSelector } from 'react-redux';
-
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
+import React from 'react';
 
+import { useGlobalPref } from '../../hooks/useGlobalPref';
 import { useResponsive } from '../../ResponsiveProvider';
 import { View } from '../common/View';
 
-import { SIDEBAR_WIDTH } from './Sidebar';
-import { SidebarWithData } from './SidebarWithData';
-
-type SidebarContextValue = {
-  hidden: boolean;
-  setHidden: Dispatch<SetStateAction<boolean>>;
-  floating: boolean;
-  alwaysFloats: boolean;
-};
-
-const SidebarContext = createContext<SidebarContextValue>(null);
-
-type SidebarProviderProps = {
-  children: ReactNode;
-};
-
-export function SidebarProvider({ children }: SidebarProviderProps) {
-  const floatingSidebar = useSelector<
-    State,
-    PrefsState['global']['floatingSidebar']
-  >(state => state.prefs.global.floatingSidebar);
-  const [hidden, setHidden] = useState(true);
-  const { width } = useResponsive();
-  const alwaysFloats = width < 668;
-  const floating = floatingSidebar || alwaysFloats;
-
-  return (
-    <SidebarContext.Provider
-      value={{ hidden, setHidden, floating, alwaysFloats }}
-    >
-      {children}
-    </SidebarContext.Provider>
-  );
-}
-
-export function useSidebar() {
-  const { hidden, setHidden, floating, alwaysFloats } =
-    useContext(SidebarContext);
-
-  return useMemo(
-    () => ({ hidden, setHidden, floating, alwaysFloats }),
-    [hidden, setHidden, floating, alwaysFloats],
-  );
-}
+import { SIDEBAR_WIDTH, Sidebar } from './Sidebar';
+import { useSidebar } from './SidebarProvider';
 
 export function FloatableSidebar() {
-  const floatingSidebar = useSelector<
-    State,
-    PrefsState['global']['floatingSidebar']
-  >(state => state.prefs.global.floatingSidebar);
+  const [floatingSidebar] = useGlobalPref('floatingSidebar');
 
   const sidebar = useSidebar();
   const { isNarrowWidth } = useResponsive();
@@ -80,11 +23,13 @@ export function FloatableSidebar() {
               e.stopPropagation();
               sidebar.setHidden(false);
             }
-          : null
+          : undefined
+      }
+      onMouseLeave={
+        sidebarShouldFloat ? () => sidebar.setHidden(true) : undefined
       }
-      onMouseLeave={sidebarShouldFloat ? () => sidebar.setHidden(true) : null}
       style={{
-        position: sidebarShouldFloat ? 'absolute' : null,
+        position: sidebarShouldFloat ? 'absolute' : undefined,
         top: 12,
         // If not floating, the -50 takes into account the transform below
         bottom: sidebarShouldFloat ? 12 : -50,
@@ -105,7 +50,7 @@ export function FloatableSidebar() {
           'transform .5s, box-shadow .5s, border-radius .5s, bottom .5s',
       }}
     >
-      <SidebarWithData />
+      <Sidebar />
     </View>
   );
 }
diff --git a/packages/desktop-client/src/components/transactions/MobileTransaction.jsx b/packages/desktop-client/src/components/transactions/MobileTransaction.jsx
index bda688058..bbce43aee 100644
--- a/packages/desktop-client/src/components/transactions/MobileTransaction.jsx
+++ b/packages/desktop-client/src/components/transactions/MobileTransaction.jsx
@@ -46,9 +46,12 @@ import {
   groupById,
 } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useActions } from '../../hooks/useActions';
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
 import { useNavigate } from '../../hooks/useNavigate';
+import { usePayees } from '../../hooks/usePayees';
 import { useSetThemeColor } from '../../hooks/useSetThemeColor';
 import {
   SingleActiveEditFormProvider,
@@ -939,11 +942,6 @@ function TransactionEditUnconnected(props) {
   useSetThemeColor(theme.mobileViewTheme);
 
   useEffect(() => {
-    // May as well update categories / accounts when transaction ID changes
-    props.getCategories();
-    props.getAccounts();
-    props.getPayees();
-
     async function fetchTransaction() {
       // Query for the transaction based on the ID with grouped splits.
       //
@@ -1110,12 +1108,10 @@ function TransactionEditUnconnected(props) {
 
 export const TransactionEdit = props => {
   const { list: categories } = useCategories();
-  const payees = useSelector(state => state.queries.payees);
+  const payees = usePayees();
   const lastTransaction = useSelector(state => state.queries.lastTransaction);
-  const accounts = useSelector(state => state.queries.accounts);
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const accounts = useAccounts();
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
   const actions = useActions();
 
   return (
diff --git a/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.jsx b/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.jsx
index ea43f6adb..736df89d2 100644
--- a/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.jsx
+++ b/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.jsx
@@ -1,5 +1,4 @@
-import React, { memo, useCallback, useMemo } from 'react';
-import { useSelector } from 'react-redux';
+import React, { memo, useMemo, useCallback } from 'react';
 
 import {
   format as formatDate,
@@ -13,8 +12,11 @@ import {
 } from 'loot-core/src/client/reducers/queries';
 import { integerToCurrency } from 'loot-core/src/shared/util';
 
+import { useAccounts } from '../../hooks/useAccounts';
 import { useCategories } from '../../hooks/useCategories';
-import { useSelectedDispatch, useSelectedItems } from '../../hooks/useSelected';
+import { useDateFormat } from '../../hooks/useDateFormat';
+import { usePayees } from '../../hooks/usePayees';
+import { useSelectedItems, useSelectedDispatch } from '../../hooks/useSelected';
 import { SvgArrowsSynchronize } from '../../icons/v2';
 import { styles, theme } from '../../style';
 import { Cell, Field, Row, SelectCell, Table } from '../table';
@@ -141,13 +143,9 @@ export function SimpleTransactionsTable({
   style,
 }) {
   const { grouped: categories } = useCategories();
-  const { payees, accounts, dateFormat } = useSelector(state => {
-    return {
-      payees: state.queries.payees,
-      accounts: state.queries.accounts,
-      dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy',
-    };
-  });
+  const payees = usePayees();
+  const accounts = useAccounts();
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
   const selectedItems = useSelectedItems();
   const dispatchSelected = useSelectedDispatch();
   const memoFields = useMemo(() => fields, [JSON.stringify(fields)]);
diff --git a/packages/desktop-client/src/components/util/DisplayId.tsx b/packages/desktop-client/src/components/util/DisplayId.tsx
index db3982cbe..34c5f593a 100644
--- a/packages/desktop-client/src/components/util/DisplayId.tsx
+++ b/packages/desktop-client/src/components/util/DisplayId.tsx
@@ -1,9 +1,8 @@
 // @ts-strict-ignore
 import React from 'react';
 
-import { CachedAccounts } from 'loot-core/src/client/data-hooks/accounts';
-import { CachedPayees } from 'loot-core/src/client/data-hooks/payees';
-
+import { useAccount } from '../../hooks/useAccount';
+import { usePayee } from '../../hooks/usePayee';
 import { theme } from '../../style';
 import { Text } from '../common/Text';
 
@@ -18,33 +17,33 @@ export function DisplayId({
   id,
   noneColor = theme.pageTextSubdued,
 }: DisplayIdProps) {
-  let DataComponent;
-
-  switch (type) {
-    case 'payees':
-      DataComponent = CachedPayees;
-      break;
-    case 'accounts':
-      DataComponent = CachedAccounts;
-      break;
-    default:
-      throw new Error('DisplayId: unknown object type: ' + type);
-  }
+  return type === 'accounts' ? (
+    <AccountDisplayId id={id} noneColor={noneColor} />
+  ) : (
+    <PayeeDisplayId id={id} noneColor={noneColor} />
+  );
+}
 
+function AccountDisplayId({ id, noneColor }) {
+  const account = useAccount(id);
   return (
-    <DataComponent idKey={true}>
-      {data => {
-        const item = data[id];
+    <Text
+      style={account == null ? { color: noneColor } : null}
+      title={account ? account.name : 'None'}
+    >
+      {account ? account.name : 'None'}
+    </Text>
+  );
+}
 
-        return (
-          <Text
-            style={item == null ? { color: noneColor } : null}
-            title={item ? item.name : 'None'}
-          >
-            {item ? item.name : 'None'}
-          </Text>
-        );
-      }}
-    </DataComponent>
+function PayeeDisplayId({ id, noneColor }) {
+  const payee = usePayee(id);
+  return (
+    <Text
+      style={payee == null ? { color: noneColor } : null}
+      title={payee ? payee.name : 'None'}
+    >
+      {payee ? payee.name : 'None'}
+    </Text>
   );
 }
diff --git a/packages/desktop-client/src/components/util/GenericInput.jsx b/packages/desktop-client/src/components/util/GenericInput.jsx
index b42826e01..bf2e3c53d 100644
--- a/packages/desktop-client/src/components/util/GenericInput.jsx
+++ b/packages/desktop-client/src/components/util/GenericInput.jsx
@@ -4,6 +4,7 @@ import { useSelector } from 'react-redux';
 import { getMonthYearFormat } from 'loot-core/src/shared/months';
 
 import { useCategories } from '../../hooks/useCategories';
+import { useDateFormat } from '../../hooks/useDateFormat';
 import { AccountAutocomplete } from '../autocomplete/AccountAutocomplete';
 import { Autocomplete } from '../autocomplete/Autocomplete';
 import { CategoryAutocomplete } from '../autocomplete/CategoryAutocomplete';
@@ -27,9 +28,7 @@ export function GenericInput({
 }) {
   const { grouped: categoryGroups } = useCategories();
   const saved = useSelector(state => state.queries.saved);
-  const dateFormat = useSelector(
-    state => state.prefs.local.dateFormat || 'MM/dd/yyyy',
-  );
+  const dateFormat = useDateFormat() || 'MM/dd/yyyy';
 
   // This makes the UI more resilient in case of faulty data
   if (multi && !Array.isArray(value)) {
diff --git a/packages/desktop-client/src/hooks/useAccount.ts b/packages/desktop-client/src/hooks/useAccount.ts
new file mode 100644
index 000000000..e3da8f35e
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useAccount.ts
@@ -0,0 +1,8 @@
+import { useMemo } from 'react';
+
+import { useAccounts } from './useAccounts';
+
+export function useAccount(id: string) {
+  const accounts = useAccounts();
+  return useMemo(() => accounts.find(a => a.id === id), [id, accounts]);
+}
diff --git a/packages/desktop-client/src/hooks/useAccounts.ts b/packages/desktop-client/src/hooks/useAccounts.ts
new file mode 100644
index 000000000..4c44e9cec
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useAccounts.ts
@@ -0,0 +1,20 @@
+import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+
+import { getAccounts } from 'loot-core/src/client/actions';
+import { type State } from 'loot-core/src/client/state-types';
+
+export function useAccounts() {
+  const dispatch = useDispatch();
+  const accountsLoaded = useSelector(
+    (state: State) => state.queries.accountsLoaded,
+  );
+
+  useEffect(() => {
+    if (!accountsLoaded) {
+      dispatch(getAccounts());
+    }
+  }, []);
+
+  return useSelector(state => state.queries.accounts);
+}
diff --git a/packages/desktop-client/src/hooks/useBudgetedAccounts.ts b/packages/desktop-client/src/hooks/useBudgetedAccounts.ts
new file mode 100644
index 000000000..dbd8e1f53
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useBudgetedAccounts.ts
@@ -0,0 +1,14 @@
+import { useMemo } from 'react';
+
+import { useAccounts } from './useAccounts';
+
+export function useBudgetedAccounts() {
+  const accounts = useAccounts();
+  return useMemo(
+    () =>
+      accounts.filter(
+        account => account.closed === 0 && account.offbudget === 0,
+      ),
+    [accounts],
+  );
+}
diff --git a/packages/desktop-client/src/hooks/useCategories.ts b/packages/desktop-client/src/hooks/useCategories.ts
index 8e2730915..4c85fdfaf 100644
--- a/packages/desktop-client/src/hooks/useCategories.ts
+++ b/packages/desktop-client/src/hooks/useCategories.ts
@@ -1,25 +1,20 @@
 import { useEffect } from 'react';
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type QueriesState } from 'loot-core/client/state-types/queries';
-
-import { useActions } from './useActions';
+import { getCategories } from 'loot-core/src/client/actions';
+import { type State } from 'loot-core/src/client/state-types';
 
 export function useCategories() {
-  const { getCategories } = useActions();
-
-  const categories = useSelector<State, QueriesState['categories']['list']>(
-    state => state.queries.categories.list,
+  const dispatch = useDispatch();
+  const categoriesLoaded = useSelector(
+    (state: State) => state.queries.categoriesLoaded,
   );
 
   useEffect(() => {
-    if (categories.length === 0) {
-      getCategories();
+    if (!categoriesLoaded) {
+      dispatch(getCategories());
     }
   }, []);
 
-  return useSelector<State, QueriesState['categories']>(
-    state => state.queries.categories,
-  );
+  return useSelector(state => state.queries.categories);
 }
diff --git a/packages/desktop-client/src/hooks/useClosedAccounts.ts b/packages/desktop-client/src/hooks/useClosedAccounts.ts
new file mode 100644
index 000000000..85aa5b920
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useClosedAccounts.ts
@@ -0,0 +1,11 @@
+import { useMemo } from 'react';
+
+import { useAccounts } from './useAccounts';
+
+export function useClosedAccounts() {
+  const accounts = useAccounts();
+  return useMemo(
+    () => accounts.filter(account => account.closed === 1),
+    [accounts],
+  );
+}
diff --git a/packages/desktop-client/src/hooks/useDateFormat.ts b/packages/desktop-client/src/hooks/useDateFormat.ts
new file mode 100644
index 000000000..258f156e1
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useDateFormat.ts
@@ -0,0 +1,7 @@
+import { useSelector } from 'react-redux';
+
+import { type State } from 'loot-core/src/client/state-types';
+
+export function useDateFormat() {
+  return useSelector((state: State) => state.prefs.local?.dateFormat);
+}
diff --git a/packages/desktop-client/src/hooks/useFailedAccounts.ts b/packages/desktop-client/src/hooks/useFailedAccounts.ts
new file mode 100644
index 000000000..86aeb8995
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useFailedAccounts.ts
@@ -0,0 +1,7 @@
+import { useSelector } from 'react-redux';
+
+import { type State } from 'loot-core/src/client/state-types';
+
+export function useFailedAccounts() {
+  return useSelector((state: State) => state.account.failedAccounts);
+}
diff --git a/packages/desktop-client/src/hooks/useFeatureFlag.ts b/packages/desktop-client/src/hooks/useFeatureFlag.ts
index 40b79b84d..5550cfed2 100644
--- a/packages/desktop-client/src/hooks/useFeatureFlag.ts
+++ b/packages/desktop-client/src/hooks/useFeatureFlag.ts
@@ -1,8 +1,7 @@
 // @ts-strict-ignore
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
+import { type State } from 'loot-core/src/client/state-types';
 import type { FeatureFlag } from 'loot-core/src/types/prefs';
 
 const DEFAULT_FEATURE_FLAG_STATE: Record<FeatureFlag, boolean> = {
@@ -15,13 +14,11 @@ const DEFAULT_FEATURE_FLAG_STATE: Record<FeatureFlag, boolean> = {
 };
 
 export function useFeatureFlag(name: FeatureFlag): boolean {
-  return useSelector<State, PrefsState['local'][`flags.${FeatureFlag}`]>(
-    state => {
-      const value = state.prefs.local[`flags.${name}`];
+  return useSelector((state: State) => {
+    const value = state.prefs.local[`flags.${name}`];
 
-      return value === undefined
-        ? DEFAULT_FEATURE_FLAG_STATE[name] || false
-        : value;
-    },
-  );
+    return value === undefined
+      ? DEFAULT_FEATURE_FLAG_STATE[name] || false
+      : value;
+  });
 }
diff --git a/packages/desktop-client/src/hooks/useGlobalPref.ts b/packages/desktop-client/src/hooks/useGlobalPref.ts
new file mode 100644
index 000000000..02d5773ac
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useGlobalPref.ts
@@ -0,0 +1,27 @@
+import { useCallback } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+
+import { saveGlobalPrefs } from 'loot-core/src/client/actions';
+import { type State } from 'loot-core/src/client/state-types';
+import { type GlobalPrefs } from 'loot-core/src/types/prefs';
+
+type SetGlobalPrefAction<K extends keyof GlobalPrefs> = (
+  value: GlobalPrefs[K],
+) => void;
+
+export function useGlobalPref<K extends keyof GlobalPrefs>(
+  prefName: K,
+): [GlobalPrefs[K], SetGlobalPrefAction<K>] {
+  const dispatch = useDispatch();
+  const setGlobalPref = useCallback<SetGlobalPrefAction<K>>(
+    value => {
+      dispatch(saveGlobalPrefs({ [prefName]: value } as GlobalPrefs));
+    },
+    [prefName, dispatch],
+  );
+  const globalPref = useSelector(
+    (state: State) => state.prefs.global?.[prefName] as GlobalPrefs[K],
+  );
+
+  return [globalPref, setGlobalPref];
+}
diff --git a/packages/desktop-client/src/hooks/useLocalPref.ts b/packages/desktop-client/src/hooks/useLocalPref.ts
new file mode 100644
index 000000000..70a50cb55
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useLocalPref.ts
@@ -0,0 +1,27 @@
+import { useCallback } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+
+import { savePrefs } from 'loot-core/src/client/actions';
+import { type State } from 'loot-core/src/client/state-types';
+import { type LocalPrefs } from 'loot-core/src/types/prefs';
+
+type SetLocalPrefAction<K extends keyof LocalPrefs> = (
+  value: LocalPrefs[K],
+) => void;
+
+export function useLocalPref<K extends keyof LocalPrefs>(
+  prefName: K,
+): [LocalPrefs[K], SetLocalPrefAction<K>] {
+  const dispatch = useDispatch();
+  const setLocalPref = useCallback<SetLocalPrefAction<K>>(
+    value => {
+      dispatch(savePrefs({ [prefName]: value } as LocalPrefs));
+    },
+    [prefName, dispatch],
+  );
+  const localPref = useSelector(
+    (state: State) => state.prefs.local?.[prefName] as LocalPrefs[K],
+  );
+
+  return [localPref, setLocalPref];
+}
diff --git a/packages/desktop-client/src/hooks/useLocalPrefs.ts b/packages/desktop-client/src/hooks/useLocalPrefs.ts
new file mode 100644
index 000000000..870bef808
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useLocalPrefs.ts
@@ -0,0 +1,7 @@
+import { useSelector } from 'react-redux';
+
+import { type State } from 'loot-core/src/client/state-types';
+
+export function useLocalPrefs() {
+  return useSelector((state: State) => state.prefs.local);
+}
diff --git a/packages/desktop-client/src/hooks/useOffBudgetAccounts.ts b/packages/desktop-client/src/hooks/useOffBudgetAccounts.ts
new file mode 100644
index 000000000..71a5db919
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useOffBudgetAccounts.ts
@@ -0,0 +1,14 @@
+import { useMemo } from 'react';
+
+import { useAccounts } from './useAccounts';
+
+export function useOffBudgetAccounts() {
+  const accounts = useAccounts();
+  return useMemo(
+    () =>
+      accounts.filter(
+        account => account.closed === 0 && account.offbudget === 1,
+      ),
+    [accounts],
+  );
+}
diff --git a/packages/desktop-client/src/hooks/usePayee.ts b/packages/desktop-client/src/hooks/usePayee.ts
new file mode 100644
index 000000000..2606c60a8
--- /dev/null
+++ b/packages/desktop-client/src/hooks/usePayee.ts
@@ -0,0 +1,8 @@
+import { useMemo } from 'react';
+
+import { usePayees } from './usePayees';
+
+export function usePayee(id: string) {
+  const payees = usePayees();
+  return useMemo(() => payees.find(p => p.id === id), [id, payees]);
+}
diff --git a/packages/desktop-client/src/hooks/usePayees.ts b/packages/desktop-client/src/hooks/usePayees.ts
new file mode 100644
index 000000000..cf51d6b9a
--- /dev/null
+++ b/packages/desktop-client/src/hooks/usePayees.ts
@@ -0,0 +1,20 @@
+import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+
+import { getPayees } from 'loot-core/src/client/actions';
+import { type State } from 'loot-core/src/client/state-types';
+
+export function usePayees() {
+  const dispatch = useDispatch();
+  const payeesLoaded = useSelector(
+    (state: State) => state.queries.payeesLoaded,
+  );
+
+  useEffect(() => {
+    if (!payeesLoaded) {
+      dispatch(getPayees());
+    }
+  }, []);
+
+  return useSelector(state => state.queries.payees);
+}
diff --git a/packages/desktop-client/src/hooks/usePrivacyMode.ts b/packages/desktop-client/src/hooks/usePrivacyMode.ts
new file mode 100644
index 000000000..ffa633bc0
--- /dev/null
+++ b/packages/desktop-client/src/hooks/usePrivacyMode.ts
@@ -0,0 +1,9 @@
+import { useSelector } from 'react-redux';
+
+import { type State } from 'loot-core/src/client/state-types';
+
+export function usePrivacyMode() {
+  return useSelector(
+    (state: State) => state.prefs.local?.isPrivacyEnabled ?? false,
+  );
+}
diff --git a/packages/desktop-client/src/hooks/useSelected.tsx b/packages/desktop-client/src/hooks/useSelected.tsx
index 398350e0d..63a0437a8 100644
--- a/packages/desktop-client/src/hooks/useSelected.tsx
+++ b/packages/desktop-client/src/hooks/useSelected.tsx
@@ -12,8 +12,7 @@ import React, {
 } from 'react';
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type AppState } from 'loot-core/client/state-types/app';
+import { type State } from 'loot-core/src/client/state-types';
 import { listen } from 'loot-core/src/platform/client/fetch';
 import * as undo from 'loot-core/src/platform/client/undo';
 import { type UndoState } from 'loot-core/src/server/undo';
@@ -210,9 +209,7 @@ export function useSelected<T extends Item>(
     return () => undo.setUndoState('selectedItems', prevState);
   }, [state.selectedItems]);
 
-  const lastUndoState = useSelector<State, AppState['lastUndoState']>(
-    state => state.app.lastUndoState,
-  );
+  const lastUndoState = useSelector((state: State) => state.app.lastUndoState);
 
   useEffect(() => {
     function onUndo({ messages, undoTag }: UndoState) {
diff --git a/packages/desktop-client/src/hooks/useSyncServerStatus.ts b/packages/desktop-client/src/hooks/useSyncServerStatus.ts
index 2b48a0c6f..d788340be 100644
--- a/packages/desktop-client/src/hooks/useSyncServerStatus.ts
+++ b/packages/desktop-client/src/hooks/useSyncServerStatus.ts
@@ -1,7 +1,6 @@
 import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type UserState } from 'loot-core/client/state-types/user';
+import { type State } from 'loot-core/src/client/state-types';
 
 import { useServerURL } from '../components/ServerContext';
 
@@ -9,9 +8,7 @@ export type SyncServerStatus = 'offline' | 'no-server' | 'online';
 
 export function useSyncServerStatus(): SyncServerStatus {
   const serverUrl = useServerURL();
-  const userData = useSelector<State, UserState['data']>(
-    state => state.user.data,
-  );
+  const userData = useSelector((state: State) => state.user.data);
 
   if (!serverUrl) {
     return 'no-server';
diff --git a/packages/desktop-client/src/hooks/useUpdatedAccounts.ts b/packages/desktop-client/src/hooks/useUpdatedAccounts.ts
new file mode 100644
index 000000000..483d22c9b
--- /dev/null
+++ b/packages/desktop-client/src/hooks/useUpdatedAccounts.ts
@@ -0,0 +1,7 @@
+import { useSelector } from 'react-redux';
+
+import { type State } from 'loot-core/src/client/state-types';
+
+export function useUpdatedAccounts() {
+  return useSelector((state: State) => state.queries.updatedAccounts);
+}
diff --git a/packages/desktop-client/src/style/theme.tsx b/packages/desktop-client/src/style/theme.tsx
index 7cd3b5751..fe6b2374d 100644
--- a/packages/desktop-client/src/style/theme.tsx
+++ b/packages/desktop-client/src/style/theme.tsx
@@ -1,12 +1,11 @@
 // @ts-strict-ignore
 import { useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
 
-import { type State } from 'loot-core/client/state-types';
-import { type PrefsState } from 'loot-core/client/state-types/prefs';
 import { isNonProductionEnvironment } from 'loot-core/src/shared/environment';
 import type { Theme } from 'loot-core/src/types/prefs';
 
+import { useGlobalPref } from '../hooks/useGlobalPref';
+
 import * as darkTheme from './themes/dark';
 import * as developmentTheme from './themes/development';
 import * as lightTheme from './themes/light';
@@ -24,16 +23,13 @@ export const themeOptions = Object.entries(themes).map(
   ([key, { name }]) => [key, name] as [Theme, string],
 );
 
-export function useTheme(): Theme {
-  return (
-    useSelector<State, PrefsState['global']['theme']>(
-      state => state.prefs.global?.theme,
-    ) || 'light'
-  );
+export function useTheme() {
+  const [theme = 'light', setThemePref] = useGlobalPref('theme');
+  return [theme, setThemePref] as const;
 }
 
 export function ThemeStyle() {
-  const theme = useTheme();
+  const [theme] = useTheme();
   const [themeColors, setThemeColors] = useState<
     typeof lightTheme | typeof darkTheme | undefined
   >(undefined);
diff --git a/packages/loot-core/src/client/actions/account.ts b/packages/loot-core/src/client/actions/account.ts
index c8349d84c..e7f7f269b 100644
--- a/packages/loot-core/src/client/actions/account.ts
+++ b/packages/loot-core/src/client/actions/account.ts
@@ -263,3 +263,10 @@ export function markAccountRead(accountId): MarkAccountReadAction {
     accountId,
   };
 }
+
+export function moveAccount(id, targetId) {
+  return async (dispatch: Dispatch) => {
+    await send('account-move', { id, targetId });
+    dispatch(getAccounts());
+  };
+}
diff --git a/packages/loot-core/src/client/actions/prefs.ts b/packages/loot-core/src/client/actions/prefs.ts
index b93a38eb3..5dbca103f 100644
--- a/packages/loot-core/src/client/actions/prefs.ts
+++ b/packages/loot-core/src/client/actions/prefs.ts
@@ -26,7 +26,7 @@ export function loadPrefs() {
   };
 }
 
-export function savePrefs(prefs: Partial<prefs.LocalPrefs>) {
+export function savePrefs(prefs: prefs.LocalPrefs) {
   return async (dispatch: Dispatch) => {
     await send('save-prefs', prefs);
     dispatch({
@@ -48,7 +48,7 @@ export function loadGlobalPrefs() {
   };
 }
 
-export function saveGlobalPrefs(prefs: Partial<prefs.GlobalPrefs>) {
+export function saveGlobalPrefs(prefs: prefs.GlobalPrefs) {
   return async (dispatch: Dispatch) => {
     await send('save-global-prefs', prefs);
     dispatch({
diff --git a/packages/loot-core/src/client/data-hooks/accounts.tsx b/packages/loot-core/src/client/data-hooks/accounts.tsx
deleted file mode 100644
index c2460477f..000000000
--- a/packages/loot-core/src/client/data-hooks/accounts.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-// @ts-strict-ignore
-import React, { createContext, useContext } from 'react';
-
-import { q } from '../../shared/query';
-import { type AccountEntity } from '../../types/models';
-import { useLiveQuery } from '../query-hooks';
-import { getAccountsById } from '../reducers/queries';
-
-function useAccounts(): AccountEntity[] {
-  return useLiveQuery(() => q('accounts').select('*'), []);
-}
-
-const AccountsContext = createContext<AccountEntity[]>(null);
-
-export function AccountsProvider({ children }) {
-  const data = useAccounts();
-  return (
-    <AccountsContext.Provider value={data}>{children}</AccountsContext.Provider>
-  );
-}
-
-export function CachedAccounts({ children, idKey }) {
-  const data = useCachedAccounts({ idKey });
-  return children(data);
-}
-
-export function useCachedAccounts(): AccountEntity[];
-export function useCachedAccounts({
-  idKey,
-}: {
-  idKey: boolean;
-}): Record<AccountEntity['id'], AccountEntity>;
-export function useCachedAccounts({ idKey }: { idKey?: boolean } = {}) {
-  const data = useContext(AccountsContext);
-  return idKey && data ? getAccountsById(data) : data;
-}
diff --git a/packages/loot-core/src/client/data-hooks/payees.tsx b/packages/loot-core/src/client/data-hooks/payees.tsx
deleted file mode 100644
index 4299aa9a3..000000000
--- a/packages/loot-core/src/client/data-hooks/payees.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-// @ts-strict-ignore
-import React, { createContext, useContext } from 'react';
-
-import { q } from '../../shared/query';
-import { type PayeeEntity } from '../../types/models';
-import { useLiveQuery } from '../query-hooks';
-import { getPayeesById } from '../reducers/queries';
-
-function usePayees(): PayeeEntity[] {
-  return useLiveQuery(() => q('payees').select('*'), []);
-}
-
-const PayeesContext = createContext<PayeeEntity[]>(null);
-
-export function PayeesProvider({ children }) {
-  const data = usePayees();
-  return (
-    <PayeesContext.Provider value={data}>{children}</PayeesContext.Provider>
-  );
-}
-
-export function CachedPayees({ children, idKey }) {
-  const data = useCachedPayees({ idKey });
-  return children(data);
-}
-
-export function useCachedPayees(): PayeeEntity[];
-export function useCachedPayees({
-  idKey,
-}: {
-  idKey: boolean;
-}): Record<PayeeEntity['id'], PayeeEntity>;
-export function useCachedPayees({ idKey }: { idKey?: boolean } = {}) {
-  const data = useContext(PayeesContext);
-  return idKey && data ? getPayeesById(data) : data;
-}
diff --git a/packages/loot-core/src/client/privacy.ts b/packages/loot-core/src/client/privacy.ts
deleted file mode 100644
index 295bba5e5..000000000
--- a/packages/loot-core/src/client/privacy.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { useSelector } from 'react-redux';
-
-export function usePrivacyMode() {
-  return useSelector(state => state.prefs?.local?.isPrivacyEnabled ?? false);
-}
diff --git a/packages/loot-core/src/client/reducers/queries.ts b/packages/loot-core/src/client/reducers/queries.ts
index 470c35916..b0c38817a 100644
--- a/packages/loot-core/src/client/reducers/queries.ts
+++ b/packages/loot-core/src/client/reducers/queries.ts
@@ -13,11 +13,14 @@ const initialState: QueriesState = {
   lastTransaction: null,
   updatedAccounts: [],
   accounts: [],
+  accountsLoaded: false,
   categories: {
     grouped: [],
     list: [],
   },
+  categoriesLoaded: false,
   payees: [],
+  payeesLoaded: false,
   earliestTransaction: null,
 };
 
@@ -56,6 +59,7 @@ export function update(state = initialState, action: Action): QueriesState {
       return {
         ...state,
         accounts: action.accounts,
+        accountsLoaded: true,
       };
     case constants.UPDATE_ACCOUNT: {
       return {
@@ -72,11 +76,13 @@ export function update(state = initialState, action: Action): QueriesState {
       return {
         ...state,
         categories: action.categories,
+        categoriesLoaded: true,
       };
     case constants.LOAD_PAYEES:
       return {
         ...state,
         payees: action.payees,
+        payeesLoaded: true,
       };
     default:
   }
diff --git a/packages/loot-core/src/client/state-types/modals.d.ts b/packages/loot-core/src/client/state-types/modals.d.ts
index e25e38feb..72cd5dbc5 100644
--- a/packages/loot-core/src/client/state-types/modals.d.ts
+++ b/packages/loot-core/src/client/state-types/modals.d.ts
@@ -42,7 +42,7 @@ type FinanceModals = {
     syncSource?: AccountSyncSource;
   };
 
-  'confirm-category-delete': { onDelete: () => void } & (
+  'confirm-category-delete': { onDelete: (categoryId: string) => void } & (
     | { category: string }
     | { group: string }
   );
diff --git a/packages/loot-core/src/client/state-types/queries.d.ts b/packages/loot-core/src/client/state-types/queries.d.ts
index a7f18526f..0d511868b 100644
--- a/packages/loot-core/src/client/state-types/queries.d.ts
+++ b/packages/loot-core/src/client/state-types/queries.d.ts
@@ -8,8 +8,11 @@ export type QueriesState = {
   lastTransaction: unknown | null;
   updatedAccounts: string[];
   accounts: AccountEntity[];
+  accountsLoaded: boolean;
   categories: Awaited<ReturnType<Handlers['get-categories']>>;
+  categoriesLoaded: boolean;
   payees: Awaited<ReturnType<Handlers['payees-get']>>;
+  payeesLoaded: boolean;
   earliestTransaction: unknown | null;
 };
 
diff --git a/packages/loot-core/src/shared/categories.ts b/packages/loot-core/src/shared/categories.ts
deleted file mode 100644
index 9e2c4c190..000000000
--- a/packages/loot-core/src/shared/categories.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-// @ts-strict-ignore
-export function addCategory(categoryGroups, cat) {
-  return categoryGroups.map(group => {
-    if (group.id === cat.cat_group) {
-      group.categories = [cat, ...group.categories];
-    }
-    return { ...group };
-  });
-}
-
-export function updateCategory(categoryGroups, category) {
-  return categoryGroups.map(group => {
-    if (group.id === category.cat_group) {
-      group.categories = group.categories.map(c => {
-        if (c.id === category.id) {
-          return { ...c, ...category };
-        }
-        return c;
-      });
-    }
-    return group;
-  });
-}
-
-export function moveCategory(categoryGroups, id, groupId, targetId) {
-  if (id === targetId) {
-    return categoryGroups;
-  }
-
-  let moveCat = categoryGroups.reduce((value, group) => {
-    return value || group.categories.find(cat => cat.id === id);
-  }, null);
-
-  // Update the group id on the category
-  moveCat = { ...moveCat, cat_group: groupId };
-
-  return categoryGroups.map(group => {
-    if (group.id === groupId) {
-      group.categories = group.categories.reduce((cats, cat) => {
-        if (cat.id === targetId) {
-          cats.push(moveCat);
-          cats.push(cat);
-        } else if (cat.id !== id) {
-          cats.push(cat);
-        }
-        return cats;
-      }, []);
-
-      if (!targetId) {
-        group.categories.push(moveCat);
-      }
-    } else {
-      group.categories = group.categories.filter(cat => cat.id !== id);
-    }
-
-    return { ...group };
-  });
-}
-
-export function moveCategoryGroup(categoryGroups, id, targetId) {
-  if (id === targetId) {
-    return categoryGroups;
-  }
-
-  const moveGroup = categoryGroups.find(g => g.id === id);
-
-  categoryGroups = categoryGroups.reduce((groups, group) => {
-    if (group.id === targetId) {
-      groups.push(moveGroup);
-      groups.push(group);
-    } else if (group.id !== id) {
-      groups.push(group);
-    }
-    return groups;
-  }, []);
-
-  if (!targetId) {
-    categoryGroups.push(moveGroup);
-  }
-
-  return categoryGroups;
-}
-
-export function deleteCategory(categoryGroups, id) {
-  return categoryGroups.map(group => {
-    group.categories = group.categories.filter(c => c.id !== id);
-    return group;
-  });
-}
-
-export function addGroup(categoryGroups, group) {
-  return [...categoryGroups, group];
-}
-
-export function updateGroup(categoryGroups, group) {
-  return categoryGroups.map(g => {
-    if (g.id === group.id) {
-      return { ...g, ...group };
-    }
-    return g;
-  });
-}
-
-export function deleteGroup(categoryGroups, id) {
-  return categoryGroups.filter(g => g.id !== id);
-}
diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts
index df63517dd..251b6e5dd 100644
--- a/packages/loot-core/src/types/prefs.d.ts
+++ b/packages/loot-core/src/types/prefs.d.ts
@@ -53,6 +53,7 @@ export type LocalPrefs = Partial<
     reportsViewLegend: boolean;
     reportsViewSummary: boolean;
     reportsViewLabel: boolean;
+    'mobile.showSpentColumn': boolean;
   } & Record<`flags.${FeatureFlag}`, boolean>
 >;
 
diff --git a/upcoming-release-notes/2293.md b/upcoming-release-notes/2293.md
new file mode 100644
index 000000000..d65818af8
--- /dev/null
+++ b/upcoming-release-notes/2293.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [joel-jeremy]
+---
+
+Add hooks for frequently-made operations in the codebase.
-- 
GitLab