Last active
November 10, 2023 00:17
-
-
Save koenbok/ae7b94f9fefccc16a34589af344db789 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from "react"; | |
/** | |
A hook to simply use state between components | |
Warning: this only works with function components (like any hook) | |
Usage: | |
// You can put this in an central file and import it too | |
const useStore = createStore({ count: 0 }) | |
// And this is how you use it from any component | |
export function Example() { | |
const [store, setStore] = useStore() | |
const updateCount = () => setStore({ count: store.count + 1 }) | |
return <div onClick={updateCount}>{store.count}</div> | |
} | |
*/ | |
export function createStore<T>(state: T) { | |
// Store the initial state, copy the object if it's an object | |
let storeState: T = typeof state === "object" ? { ...state } : state | |
// Keep a list of all the listener, in the form of React hook setters | |
const storeSetters = new Set<Function>() | |
// Create a set function that updates all the listeners / setters | |
const setStoreState = (state: Partial<T>) => { | |
// If the state is an object, make sure we copy it | |
storeState = | |
typeof state === "object" ? { ...storeState, ...state } : state | |
// Update all the listeners / setters with the new value | |
storeSetters.forEach((setter) => setter(storeState)) | |
} | |
// Create the actual hook based on everything above | |
function useStore(): [T, typeof setStoreState] { | |
// Create the hook we are going to use as a listener | |
const [state, setState] = React.useState(storeState) | |
// If we unmount the component using this hook, we need to remove the listener | |
React.useEffect(() => () => storeSetters.delete(setState), []) | |
// But right now, we need to add the listener | |
storeSetters.add(setState) | |
// Return the state and a function to update the central store | |
return [state, setStoreState] | |
} | |
return useStore | |
} |
Great, got it working indeed. What would be the right way to get this working on a class?
EDIT: nvm, figured out it was preferably to convert old class to a function. got it working now.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It seems like TypeScript got a bit stricter with warnings, but it should totally work.