chore(orders): get rid of unnecessary stores (#4231)

This commit is contained in:
Maciek 2023-07-04 17:47:04 +02:00 committed by GitHub
parent ce3da1762b
commit efd632f5c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 77 additions and 61 deletions

View File

@ -9,10 +9,7 @@ import { t } from '@vegaprotocol/i18n';
import { OracleBanner } from '@vegaprotocol/markets'; import { OracleBanner } from '@vegaprotocol/markets';
import type { Market } from '@vegaprotocol/markets'; import type { Market } from '@vegaprotocol/markets';
import { Filter } from '@vegaprotocol/orders'; import { Filter } from '@vegaprotocol/orders';
import { import { useScreenDimensions } from '@vegaprotocol/react-helpers';
usePaneLayout,
useScreenDimensions,
} from '@vegaprotocol/react-helpers';
import { import {
Tab, Tab,
LocalStoragePersistTabs as Tabs, LocalStoragePersistTabs as Tabs,
@ -25,6 +22,7 @@ import { HeaderTitle } from '../../components/header';
import { import {
ResizableGrid, ResizableGrid,
ResizableGridPanel, ResizableGridPanel,
usePaneLayout,
} from '../../components/resizable-grid'; } from '../../components/resizable-grid';
import { TradingViews } from './trade-views'; import { TradingViews } from './trade-views';
import { MarketSelector } from './market-selector'; import { MarketSelector } from './market-selector';

View File

@ -4,7 +4,6 @@ import { LayoutPriority } from 'allotment';
import { titlefy } from '@vegaprotocol/utils'; import { titlefy } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import { useIncompleteWithdrawals } from '@vegaprotocol/withdraws'; import { useIncompleteWithdrawals } from '@vegaprotocol/withdraws';
import { usePaneLayout } from '@vegaprotocol/react-helpers';
import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit'; import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit';
import { usePageTitleStore } from '../../stores'; import { usePageTitleStore } from '../../stores';
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler'; import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
@ -20,6 +19,7 @@ import { AccountHistoryContainer } from './account-history-container';
import { import {
ResizableGrid, ResizableGrid,
ResizableGridPanel, ResizableGridPanel,
usePaneLayout,
} from '../../components/resizable-grid'; } from '../../components/resizable-grid';
const WithdrawalsIndicator = () => { const WithdrawalsIndicator = () => {

View File

@ -1 +1,2 @@
export * from './resizable-grid'; export * from './resizable-grid';
export * from './use-pane-layout';

View File

@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { VegaWalletContext } from '@vegaprotocol/wallet'; import { VegaWalletContext } from '@vegaprotocol/wallet';
import { act, render, screen } from '@testing-library/react'; import { act, render, renderHook, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import { generateMarket, generateMarketData } from '../../test-helpers'; import { generateMarket, generateMarketData } from '../../test-helpers';
import { DealTicket } from './deal-ticket'; import { DealTicket } from './deal-ticket';
import * as Schema from '@vegaprotocol/types'; import * as Schema from '@vegaprotocol/types';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { addDecimal } from '@vegaprotocol/utils'; import { addDecimal } from '@vegaprotocol/utils';
import { useOrderStore } from '@vegaprotocol/orders'; import { useCreateOrderStore } from '@vegaprotocol/orders';
jest.mock('zustand'); jest.mock('zustand');
jest.mock('./deal-ticket-fee-details', () => ({ jest.mock('./deal-ticket-fee-details', () => ({
@ -30,6 +30,9 @@ function generateJsx() {
} }
describe('DealTicket', () => { describe('DealTicket', () => {
const { result } = renderHook(() => useCreateOrderStore());
const useOrderStore = result.current;
beforeEach(() => { beforeEach(() => {
localStorage.clear(); localStorage.clear();
}); });
@ -138,7 +141,6 @@ describe('DealTicket', () => {
reduceOnly: true, reduceOnly: true,
postOnly: false, postOnly: false,
}; };
useOrderStore.setState({ useOrderStore.setState({
orders: { orders: {
[expectedOrder.marketId]: expectedOrder, [expectedOrder.marketId]: expectedOrder,

View File

@ -1,6 +1,6 @@
import omit from 'lodash/omit'; import omit from 'lodash/omit';
import { act, renderHook } from '@testing-library/react'; import { act, renderHook } from '@testing-library/react';
import { getDefaultOrder, useOrderStore } from '@vegaprotocol/orders'; import { getDefaultOrder, useCreateOrderStore } from '@vegaprotocol/orders';
import { useOrderForm } from './use-order-form'; import { useOrderForm } from './use-order-form';
jest.mock('zustand'); jest.mock('zustand');
@ -10,6 +10,8 @@ describe('useOrderForm', () => {
const setup = (marketId: string) => { const setup = (marketId: string) => {
return renderHook(() => useOrderForm(marketId)); return renderHook(() => useOrderForm(marketId));
}; };
const { result } = renderHook(() => useCreateOrderStore());
const useOrderStore = result.current;
it('updates form fields when the order changes', async () => { it('updates form fields when the order changes', async () => {
const order = getDefaultOrder(marketId); const order = getDefaultOrder(marketId);

View File

@ -9,7 +9,7 @@ import type {
MarketDepthUpdateSubscription, MarketDepthUpdateSubscription,
PriceLevelFieldsFragment, PriceLevelFieldsFragment,
} from './__generated__/MarketDepth'; } from './__generated__/MarketDepth';
import { useOrderStore } from '@vegaprotocol/orders'; import { useCreateOrderStore } from '@vegaprotocol/orders';
export type OrderbookData = { export type OrderbookData = {
asks: PriceLevelFieldsFragment[]; asks: PriceLevelFieldsFragment[];
@ -50,8 +50,8 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
dataProvider: marketDataProvider, dataProvider: marketDataProvider,
variables, variables,
}); });
const useOrderStoreRef = useCreateOrderStore();
const updateOrder = useOrderStore((store) => store.update); const updateOrder = useOrderStoreRef((store) => store.update);
return ( return (
<AsyncRenderer <AsyncRenderer

View File

@ -2,16 +2,17 @@ import {
getDefaultOrder, getDefaultOrder,
STORAGE_KEY, STORAGE_KEY,
useOrder, useOrder,
useOrderStore, useCreateOrderStore,
} from './use-order-store'; } from './use-order-store';
import { act, renderHook } from '@testing-library/react'; import { act, renderHook } from '@testing-library/react';
import { OrderType } from '@vegaprotocol/types'; import { OrderType } from '@vegaprotocol/types';
jest.mock('zustand'); jest.mock('zustand');
describe('useOrderStore', () => { describe('useCreateOrderStore', () => {
const setup = () => { const setup = () => {
return renderHook(() => useOrderStore()); const { result } = renderHook(() => useCreateOrderStore());
return renderHook(() => result.current());
}; };
afterEach(() => { afterEach(() => {

View File

@ -1,6 +1,7 @@
import { OrderTimeInForce, Side } from '@vegaprotocol/types'; import { OrderTimeInForce, Side } from '@vegaprotocol/types';
import { OrderType } from '@vegaprotocol/types'; import { OrderType } from '@vegaprotocol/types';
import { useCallback, useEffect } from 'react'; import { useCallback, useEffect, useRef } from 'react';
import type { StateCreator, UseBoundStore, Mutate, StoreApi } from 'zustand';
import { create } from 'zustand'; import { create } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware'; import { persist, subscribeWithSelector } from 'zustand/middleware';
@ -31,9 +32,7 @@ interface Store {
export const STORAGE_KEY = 'vega_order_store'; export const STORAGE_KEY = 'vega_order_store';
export const useOrderStore = create<Store>()( const orderStateCreator: StateCreator<Store> = (set) => ({
persist(
subscribeWithSelector((set) => ({
orders: {}, orders: {},
update: (marketId, order, persist = true) => { update: (marketId, order, persist = true) => {
set((state) => { set((state) => {
@ -53,8 +52,13 @@ export const useOrderStore = create<Store>()(
}; };
}); });
}, },
})), });
{
let store: UseBoundStore<Mutate<StoreApi<Store>, []>> | null = null;
const getOrderStore = () => {
if (!store) {
store = create<Store>()(
persist(subscribeWithSelector(orderStateCreator), {
name: STORAGE_KEY, name: STORAGE_KEY,
partialize: (state) => { partialize: (state) => {
// only store the order in localStorage if user has edited, this avoids // only store the order in localStorage if user has edited, this avoids
@ -73,16 +77,24 @@ export const useOrderStore = create<Store>()(
orders: partializedOrders, orders: partializedOrders,
}; };
}, },
} })
)
); );
}
return store as UseBoundStore<Mutate<StoreApi<Store>, []>>;
};
export const useCreateOrderStore = () => {
const useOrderStoreRef = useRef(getOrderStore());
return useOrderStoreRef.current;
};
/** /**
* Retrieves an order from the store for a market and * Retrieves an order from the store for a market and
* creates one if it doesn't already exist * creates one if it doesn't already exist
*/ */
export const useOrder = (marketId: string) => { export const useOrder = (marketId: string) => {
const [order, _update] = useOrderStore((store) => { const useOrderStoreRef = useCreateOrderStore();
const [order, _update] = useOrderStoreRef((store) => {
return [store.orders[marketId], store.update]; return [store.orders[marketId], store.update];
}); });

View File

@ -11,5 +11,4 @@ export * from './use-theme-switcher';
export * from './use-storybook-theme-observer'; export * from './use-storybook-theme-observer';
export * from './use-yesterday'; export * from './use-yesterday';
export * from './use-previous'; export * from './use-previous';
export * from './use-pane-layout';
export * from './use-copy-timeout'; export * from './use-copy-timeout';

View File

@ -3,7 +3,7 @@ import type { AgGridReact } from 'ag-grid-react';
import { useRef } from 'react'; import { useRef } from 'react';
import { tradesWithMarketProvider } from './trades-data-provider'; import { tradesWithMarketProvider } from './trades-data-provider';
import { TradesTable } from './trades-table'; import { TradesTable } from './trades-table';
import { useOrderStore } from '@vegaprotocol/orders'; import { useCreateOrderStore } from '@vegaprotocol/orders';
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
interface TradesContainerProps { interface TradesContainerProps {
@ -12,7 +12,8 @@ interface TradesContainerProps {
export const TradesContainer = ({ marketId }: TradesContainerProps) => { export const TradesContainer = ({ marketId }: TradesContainerProps) => {
const gridRef = useRef<AgGridReact | null>(null); const gridRef = useRef<AgGridReact | null>(null);
const updateOrder = useOrderStore((store) => store.update); const useOrderStoreRef = useCreateOrderStore();
const updateOrder = useOrderStoreRef((store) => store.update);
const { data, error } = useDataProvider({ const { data, error } = useDataProvider({
dataProvider: tradesWithMarketProvider, dataProvider: tradesWithMarketProvider,