Skip to content

Instantly share code, notes, and snippets.

@behnammodi
Last active July 26, 2019 17:26
Show Gist options
  • Save behnammodi/af6185243bf1d6a1b0f01275f45bcbd1 to your computer and use it in GitHub Desktop.
Save behnammodi/af6185243bf1d6a1b0f01275f45bcbd1 to your computer and use it in GitHub Desktop.
React use beep for global state
import React, { useState, useEffect } from "react";
let initialState = {
count: 0,
num: 0
};
let globalState = { ...initialState };
const listeners = [];
function useBeep(fields = []) {
const [state, setState] = useState(initialState);
useEffect(() => {
console.log("useBeep useEffect", state);
if (fields.length > 0)
listeners.push({
setState,
fields
});
return () => {
//TODO: remove listener
};
}, []);
console.log("useBeep", state);
return [
state,
cb => {
const object = cb(globalState);
const effectedFields = Object.keys(object);
console.log("effectedFields", effectedFields);
globalState = {
...globalState,
...object
};
listeners.forEach(listener => {
if (
effectedFields.filter(effectedField =>
listener.fields.includes(effectedField)
).length > 0
)
listener.setState(globalState);
});
}
];
}
function A() {
console.log("render A");
const [state, setState] = useBeep(["count"]);
return <div>A count: {state.count}</div>;
}
function B() {
console.log("render B");
const [state, setState] = useBeep([]);
return (
<div>
B count: {state.count}{" "}
<button onClick={() => setState(({ count }) => ({ count: count + 1 }))}>
+
</button>
<button onClick={() => setState(({ count }) => ({ count: count + 1 }))}>
-
</button>
</div>
);
}
function C() {
console.log("render C");
const [state, setState] = useBeep();
return <div>C num: {state.num}</div>;
}
function D() {
console.log("render D");
const [state, setState] = useBeep();
return (
<div>
D num: {state.num}
<button onClick={() => setState(({ num }) => ({ num: num + 1 }))}>
+
</button>
<button onClick={() => setState(({ num }) => ({ num: num + 1 }))}>
-
</button>
</div>
);
}
function App() {
console.log("render App");
const [state, setState] = useBeep();
return (
<>
<div>App count: {state.count}</div>
{state.count < 5 && <A />}
<B />
<C />
<D />
</>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment