Skip to content

Instantly share code, notes, and snippets.

@jonastreub
Last active April 1, 2024 10:11
Show Gist options
  • Save jonastreub/f5f89e1bc33a12facbf11e7a41488ddf to your computer and use it in GitHub Desktop.
Save jonastreub/f5f89e1bc33a12facbf11e7a41488ddf to your computer and use it in GitHub Desktop.
Share state between Framer components using a Store
import * as React from "react"
// For sharing a search string among components
// export const searchStore = new Store("");
// Register class components on mount
// componentDidMount() { searchStore.registerComponent(this) }
// And unregister on unmount
// componentWillUnmount() { searchStore.unregisterComponent(this) }
// Using a hook for functional components automatically registers the component
// const value = searchStore.useValue()
// Updating the value automatically re-render all components
// onChange(value: string) { searchStore.value = value }
export class Store<T> {
private _value: T
constructor(initialValue: T) {
this._value = initialValue
}
get value() {
return this._value
}
set value(newValue: T) {
this._value = newValue
this.registeredComponents.forEach(component => component.forceUpdate())
this.hookHandlers.forEach(hookHandler => hookHandler())
}
private registeredComponents: React.Component[] = []
registerComponent(component: React.Component) {
this.registeredComponents.push(component)
}
deregisterComponent(component: React.Component) {
this.registeredComponents = this.registeredComponents.filter(
registeredComponent => registeredComponent !== component
)
}
private hookHandlers: (() => void)[] = []
private addHookHandler(hookHandler: () => void) {
this.hookHandlers.push(hookHandler)
}
private removeHookHandler(hookHandler: () => void) {
this.hookHandlers = this.hookHandlers.filter(
hook => hook !== hookHandler
)
}
// Comment this out if your React version doesn't support hooks
useValue() {
const [update, setUpdate] = React.useState(0)
React.useEffect(() => {
const updateHandler = () => setUpdate(update + 1)
this.addHookHandler(updateHandler)
return () => this.removeHookHandler(updateHandler)
})
return this._value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment