mirror of https://github.com/usememos/memos
chore: remove customize redux
parent
8e01eb8702
commit
0b3c77c79c
@ -1,31 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Store } from "./createStore";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactElement;
|
||||
store: Store<any, any>;
|
||||
context: React.Context<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toy-Redux Provider
|
||||
* Just for debug with the app store
|
||||
*/
|
||||
const Provider: React.FC<Props> = (props: Props) => {
|
||||
const { children, store, context: Context } = props;
|
||||
const [appState, setAppState] = useState(store.getState());
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = store.subscribe((ns) => {
|
||||
setAppState(ns);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <Context.Provider value={appState}>{children}</Context.Provider>;
|
||||
};
|
||||
|
||||
export default Provider;
|
@ -1,36 +0,0 @@
|
||||
import { Action, Reducer, State } from "./createStore";
|
||||
|
||||
interface ReducersMapObject<S extends State = any, A extends Action = any> {
|
||||
[key: string]: Reducer<S, A>;
|
||||
}
|
||||
|
||||
type StateFromReducersMapObject<M> = M extends ReducersMapObject
|
||||
? { [P in keyof M]: M[P] extends Reducer<infer S, any> ? S : never }
|
||||
: never;
|
||||
|
||||
function combineReducers<S extends State, A extends Action>(reducers: ReducersMapObject): Reducer<S, A> {
|
||||
const reducerKeys = Object.keys(reducers);
|
||||
const finalReducersObj: ReducersMapObject = {};
|
||||
|
||||
for (const key of reducerKeys) {
|
||||
if (typeof reducers[key] === "function") {
|
||||
finalReducersObj[key] = reducers[key];
|
||||
}
|
||||
}
|
||||
|
||||
return ((state: StateFromReducersMapObject<typeof reducers> = {}, action: A) => {
|
||||
let hasChanged = false;
|
||||
const nextState: StateFromReducersMapObject<typeof reducers> = {};
|
||||
|
||||
for (const key of reducerKeys) {
|
||||
const prevStateForKey = state[key];
|
||||
const nextStateForKey = finalReducersObj[key](prevStateForKey, action);
|
||||
nextState[key] = nextStateForKey;
|
||||
hasChanged = hasChanged || nextStateForKey !== prevStateForKey;
|
||||
}
|
||||
|
||||
return hasChanged ? nextState : state;
|
||||
}) as any as Reducer<S, A>;
|
||||
}
|
||||
|
||||
export default combineReducers;
|
@ -1,63 +0,0 @@
|
||||
export type State = Readonly<Record<string, any>>;
|
||||
export type Action = {
|
||||
type: string;
|
||||
payload: any;
|
||||
};
|
||||
|
||||
export type Reducer<S extends State, A extends Action> = (s: S, a: A) => S;
|
||||
type Listener<S extends State> = (ns: S, ps?: S) => void;
|
||||
type Unsubscribe = () => void;
|
||||
|
||||
export interface Store<S extends State, A extends Action> {
|
||||
dispatch: (a: A) => void;
|
||||
getState: () => S;
|
||||
subscribe: (listener: Listener<S>) => Unsubscribe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toy-Redux
|
||||
* @param preloadedState initial state
|
||||
* @param reducer reducer pure function
|
||||
* @returns store
|
||||
*/
|
||||
function createStore<S extends State, A extends Action>(preloadedState: S, reducer: Reducer<S, A>): Store<Readonly<S>, A> {
|
||||
const listeners: Listener<S>[] = [];
|
||||
let currentState = preloadedState;
|
||||
|
||||
const dispatch = (action: A) => {
|
||||
const nextState = reducer(currentState, action);
|
||||
const prevState = currentState;
|
||||
currentState = nextState;
|
||||
|
||||
for (const cb of listeners) {
|
||||
cb(currentState, prevState);
|
||||
}
|
||||
};
|
||||
|
||||
const subscribe = (listener: Listener<S>) => {
|
||||
let isSubscribed = true;
|
||||
listeners.push(listener);
|
||||
|
||||
return () => {
|
||||
if (!isSubscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = listeners.indexOf(listener);
|
||||
listeners.splice(index, 1);
|
||||
isSubscribed = false;
|
||||
};
|
||||
};
|
||||
|
||||
const getState = () => {
|
||||
return currentState;
|
||||
};
|
||||
|
||||
return {
|
||||
dispatch,
|
||||
getState,
|
||||
subscribe,
|
||||
};
|
||||
}
|
||||
|
||||
export default createStore;
|
@ -1,29 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type State = Readonly<Record<string, any>>;
|
||||
interface Action {
|
||||
type: string;
|
||||
}
|
||||
type Listener<S extends State> = (ns: S, ps?: S) => void;
|
||||
|
||||
interface Store<S extends State, A extends Action> {
|
||||
dispatch: (a: A) => void;
|
||||
getState: () => S;
|
||||
subscribe: (listener: Listener<S>) => () => void;
|
||||
}
|
||||
|
||||
export default function useSelector<S extends State, A extends Action>(store: Store<S, A>): S {
|
||||
const [state, setState] = useState(store.getState());
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = store.subscribe((ns) => {
|
||||
setState(ns);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return state;
|
||||
}
|
Loading…
Reference in New Issue