Jelajahi Sumber

Cleanup to make code a little clearer

Kirk Trombley 5 tahun lalu
induk
melakukan
e12a0ebb05
1 mengubah file dengan 19 tambahan dan 28 penghapusan
  1. 19 28
      client/src/store.js

+ 19 - 28
client/src/store.js

@@ -1,11 +1,7 @@
 import { useState, useEffect } from "react";
 
-const nameToHookName = name => "use" + name.charAt(0).toUpperCase() + name.slice(1);
-
 const shallowEq = (x, y) => x === y;
 
-const mapValues = (src, fn) => Object.fromEntries(Object.entries(src).map(([key, val]) => [key, fn(val)]));
-
 const createObservable = initial => {
   let _val = initial;
   let _listeners = [];
@@ -19,42 +15,37 @@ const createObservable = initial => {
         .filter(({ equality }) => !equality(oldValue, newValue))
         .forEach(({ callback }) => callback(newValue));
     },
-    _sub: (callback, equality) => {
-      _listeners.push({ callback, equality });
-      return () => {
-        _listeners = _listeners.filter(ln => ln.callback !== callback);
-      }
-    }
   };
 
   // name allows linters to pick this up as a hook
   const useValue = (equality = shallowEq) => {
-    const [val, setVal] = useState(_val);
-    useEffect(() => obs._sub(setVal, equality), [equality]);
+    const [val, callback] = useState(_val);
+    useEffect(() => {
+      _listeners.push({ callback, equality });
+      return () => {
+        _listeners = _listeners.filter(ln => ln.callback !== callback);
+      }
+    }, [equality]);
     return val;
   }
 
   return [obs, useValue];
 }
 
-const mergeState = (store, hooks, newState) => {
-  Object.entries(newState).forEach(([key, newValue]) => {
-    const obs = store[key];
-    if (obs) {
-      obs._set(newValue);
-    } else {
-      const [obs, hook] = createObservable(newValue);
-      store[key] = obs;
-      hooks[nameToHookName(key)] = hook;
-    }
-  });
-}
-
 export const createStore = (initial, actions = {}) => {
   const store = {};
   const hooks = {};
-  mergeState(store, hooks, initial);
-  const dispatch = mapValues(actions, act => (...args) => mergeState(store, hooks, act(...args)));
-  const selector = mapValues(store, obs => obs._get);
+  const dispatch = {};
+  const selector = {};
+  Object.entries(initial).forEach(([key, value]) => {
+    const [obs, hook] = createObservable(value);
+    const hookName = "use" + key.charAt(0).toUpperCase() + key.slice(1);
+    store[key] = obs;
+    hooks[hookName] = hook;
+  });
+  Object.entries(actions).forEach(([name, act]) => {
+    dispatch[name] = (...args) => Object.entries(act(...args)).forEach(([key, newValue]) => store[key]?._set(newValue))
+  });
+  Object.entries(store).forEach(([key, obs]) => { selector[key] = obs._get });
   return [hooks, dispatch, selector];
 }