Skip to content

Commit

Permalink
feat: add support for selector memoize (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
endv-bogdanb authored Aug 1, 2023
1 parent 918d600 commit be95c1f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@tanstack/react-query": "4.32.0",
"async-mutex": "0.4.0",
"clsx": "2.0.0",
"dequal": "2.0.3",
"graphql": "16.6.0",
"jose": "4.14.4",
"localforage": "1.10.0",
Expand All @@ -34,11 +35,13 @@
"sort-by": "1.2.0",
"swr": "2.2.0",
"urql": "4.0.5",
"use-sync-external-store": "1.2.0",
"zod": "3.21.4"
},
"devDependencies": {
"@types/react": "18.2.17",
"@types/react-dom": "18.2.7",
"@types/use-sync-external-store": "0.0.3",
"@typescript-eslint/eslint-plugin": "6.2.0",
"@typescript-eslint/parser": "6.2.0",
"@vitejs/plugin-react": "4.0.3",
Expand Down
7 changes: 5 additions & 2 deletions src/features/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { Navigate, Outlet } from "react-router";
import { tokenSlice } from "@utils";

export function ProtectedRoute() {
const session = tokenSlice.useSlice();
const session = tokenSlice.useSlice((state) => ({
token: state.token,
refreshToken: state.refreshToken,
}));

if (!session?.token || !session.refreshToken) {
if (!session.token || !session.refreshToken) {
return <Navigate to={""} />;
}

Expand Down
24 changes: 14 additions & 10 deletions src/utils/makeGlobalSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useSyncExternalStore } from "react";
import { dequal } from "dequal/lite";
import { useSyncExternalStoreWithSelector as useSyncExternalStore } from "use-sync-external-store/shim/with-selector";

type HandleSubscribe = Parameters<typeof useSyncExternalStore>[0];

Expand All @@ -14,17 +15,14 @@ export interface Selector<TState, TReturn> {
(state: TState): TReturn;
}

const defaultSelector: Selector<any, any> = (state) => state;

export const makeGlobalSlice = <TState, TAction extends AnyAction>(
reducer: Reducer<TState, TAction>,
) => {
const subscribers: Set<() => void> = new Set();

let state: TState = reducer(
undefined as unknown as TState,
{
type: "@@INIT",
} as unknown as TAction,
);
let state: TState = reducer(undefined, { type: "@@INIT" } as TAction);

const dispatch = (action: TAction) => {
state = reducer(state, action);
Expand All @@ -39,9 +37,15 @@ export const makeGlobalSlice = <TState, TAction extends AnyAction>(
};

const useSlice = <TReturn = TState>(
selector: Selector<TState, TReturn> = (_state) =>
_state as unknown as TReturn,
) => useSyncExternalStore(handleSubscribe, () => selector(state));
selector: Selector<TState, TReturn> = defaultSelector,
) =>
useSyncExternalStore(
handleSubscribe,
() => state,
undefined,
selector,
dequal,
);

return {
dispatch,
Expand Down
9 changes: 7 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@
dependencies:
"@types/node" "*"

"@types/use-sync-external-store@^0.0.3":
"@types/use-sync-external-store@0.0.3", "@types/use-sync-external-store@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
Expand Down Expand Up @@ -1867,6 +1867,11 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==

[email protected]:
version "2.0.3"
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==

detect-node-es@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
Expand Down Expand Up @@ -4400,7 +4405,7 @@ use-sidecar@^1.1.2:
detect-node-es "^1.1.0"
tslib "^2.0.0"

use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.0:
use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
Expand Down

0 comments on commit be95c1f

Please sign in to comment.