-
-
Save koenbok/ae7b94f9fefccc16a34589af344db789 to your computer and use it in GitHub Desktop.
| 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 | |
| } |
@DvDriel first of all you'd want to set up your store and impot like this: https://gist.github.com/koenbok/ae7b94f9fefccc16a34589af344db789#gistcomment-3214773
Then in your components you'd add:
const [store, setStore] = useStore()
This allows you to read the store as a regular variable {store.var}. Or to write a variable with the setStore hook setStore({varName: value}).
The store can contain a single variable or a set of objects.
@koenbok Would this also work in Framer Web? I tried to insert the code but get an error:

It seems like TypeScript got a bit stricter with warnings, but it should totally work.
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.
@jacopocolo How would the code look like if you use this to share data between two different components that both have their own file? I do not understand where you initialise the store and the value you want to share.
For instance, I have these components:
I want to share a numeric value between the slider and the dial, where do I define the store and where do I initialise this value?
Many thanks in advance!