Last active
March 16, 2022 09:51
-
-
Save DavidWells/dbb1a628b003e6a521f35bf49b5b688a to your computer and use it in GitHub Desktop.
State management via JS proxy
This file contains 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
// via https://twitter.com/judicael_andria/status/1501643071494180868 | |
/* usage | |
createStore({ | |
context: { | |
initialize state here | |
}, | |
actions: { | |
add: (context, event) => {} | |
} | |
}) | |
*/ | |
function createStore({ context, actions }) { | |
const proxy = new Proxy(context, { | |
get: (obj, prop) => { | |
if (obj[prop] == undefined) { | |
throw new Error(`${String(prop)} doesn't exist on the target object`); | |
} else { | |
return Reflect.get(obj, prop); | |
} | |
}, | |
set: (obj, prop, value) => { | |
return Reflect.set(obj, prop, value); | |
} | |
}); | |
return { | |
context: Object.freeze(proxy), | |
actions, | |
}; | |
} | |
const personsStore = createStore({ | |
context: { | |
user: { | |
username: "Judicael", | |
age: 23, | |
} | |
}, | |
actions: { | |
add: (context, event) => { | |
const { username, age } = context.user; | |
console.log('add username', username) | |
console.log('add age', age) | |
context.user.username = event.username | |
} | |
} | |
}) | |
const { age, username } = personsStore.context.user; | |
console.log('username', username) | |
console.log('age', age) | |
personsStore.actions.add(personsStore.context, { username: 'bill' }) | |
console.log('user', personsStore.context.user) |
This file contains 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
/* | |
// usage | |
createStore({ | |
context: { | |
initialize state here | |
}, | |
actions: { | |
add: (context, event) => { | |
} | |
} | |
}) | |
*/ | |
interface ICreateStoreProps<T, K> { | |
context: T; | |
actions?: K; | |
} | |
function createStore< | |
T extends Record<string, any>, | |
K extends Record<string, (context: T, event: Record<string, any>) => void> | |
>({ context, actions }: ICreateStoreProps<T, K>) { | |
type ContextType = typeof context; | |
const proxy = new Proxy(context, { | |
get: (obj: ContextType, prop: string) => { | |
if (obj[prop] == undefined) { | |
throw new Error(`${String(prop)} doesn't exist on the target object`); | |
} else { | |
return Reflect.get(obj, prop); | |
} | |
} | |
set: (obj: ContextType, prop, value) => { | |
return Reflect.set(obj, prop, value); | |
} | |
}); | |
return { | |
context: Object.freeze(proxy), | |
actions, | |
} | |
} | |
const personsStore = createStore({ | |
context: { | |
user: { | |
username: "Judicael", | |
age: 23, | |
} | |
}, | |
actions: { | |
add: (context, event) => { | |
const { username, age } = context.user; | |
console.log({ username, age }); | |
} | |
} | |
}); | |
const { age, username } = personsStore.context.user; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment