![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
@codemaskinc/store
Advanced tools
- ⚛️ updates outside react components - 🪝 easy access to all store values - ✍️ no repeating yourself - ⚡️ no unnecessary rerenders - 🚀 typescript intellisense
@codemaskinc/store
is a lightweight and flexible state management library designed for use in React applications and beyond. It simplifies the process of managing state in your application by providing a simple createStore
function that seamlessly integrates with React's built-in API, useSyncExternalStore
. This package aims to offer a straightforward solution for state management without the need for extensive type definitions or repetitive code.
createStore
function. Avoids the redundancy often encountered in Jotai, where similar code is replicated across different stores.useSyncExternalStore
.fast-deep-equal
for efficient state comparison, ensuring minimal re-renders and optimal performance.Install package using preferred package manager:
npm install @codemaskinc/store
# or
yarn add @codemaskinc/store
# or
bun add @codemaskinc/store
Create a store with initial state:
import { createStore } from '@codemaskinc/store'
export const { useStore } = createStore({
count: 0,
})
Use the returned hook in your React component:
import { useStore } from './store'
const App = () => {
const { state: { count }, actions: { setCount } } = useStore()
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(prev => prev + 1)}>Increment</button>
<button onClick={() => setCount(prev => prev - 1)}>Decrement</button>
</div>
)
}
import { createStore } from '@codemaskinc/store'
export const { actions, getState, reset, effect, useStore, useStoreEffect } = createStore({
count: 0,
name: 'John'
})
Object that contains all functions that allows for updating the store's state
Action name is generated automatically based on given key to the store count -> setCount
You can pass the next state directly, or a function that calculates it from the previous state - similary to the useState
hook
Function that returns current state of the store
const { count } = getState()
console.log(count)
Function that resets store state to the initial values
You can either pass all of the keys that you want to be reset, or if you won't pass any key WHOLE store will be reseted.
reset('count')
// Only count value will be reseted
reset()
// Whole store will be reseted
Function that allows to subscribe to store's values change and react to them
It takes callback with current store's state that will be triggered on store's change, and as a second argument it takes array of dependencies that will listen to
const dispose = effect(({ count }) => {
console.log(count)
}, ['count'])
If you won't pass any key to the dependencies it will trigger only once at the start - similarly to the useEffect
hook
React's hook that allows to access store's values and update them
It takes store's keys as arguments, if you won't provide any argument it will return the WHOLE store
It ONLY rerenders the component if the given keys' values have changed
It will return object with state, and actions. State is object with reactive fields from the store, it will rerender automatically whenever store value has changed
const { state, actions } = useStore('count')
console.log(state.count)
console.log(state.name) // ❌ error, name doesn't exist
actions.setCount(prev => prev + 1)
actions.setName('Anna') // ❌ error, setName doesn't exist
const { state, actions } = useStore()
console.log(state.count)
console.log(state.name)
actions.setCount(prev => prev + 1)
actions.setName('Anna')
React's hook that uses effect under the hood
You should use it inside React components, and in the other places you feel free to use effect
useStoreEffect(({ count }) => {
console.log(count)
}, ['count'])
Synchronizer is an util that allows you to synchronize store with something external like localStorage, database, device storage (MMKV, AsyncStorage) etc.
type Synchronizer<T> = {
value: T,
subscribe: (update: (value: T) => void, key: string) => void,
// If synchronizer doesn't have data that matches passed key, it should throw
getSnapshot: (key: string) => T | Promise<T>,
update: (value: T, key: string) => void
}
You can find sample Synchronizer
implementation for localStorage here and for react-native-mmkv here
If your app is SSR or for example you just want to have the same store shape but keep different values for different routes you can use scoped store
It returns:
StoreProvider
- Provider that passes scoped store down to the React's treewithStore
- HOC that passes scoped store down to the React's treeuseScopedStore
- React hook used to access scoped storeimport { createScopedStore } from '@codemaskinc/store'
export const { StoreProvider, useScopedStore, withStore } = createScopedStore({
count: 0,
})
import { createStore } from '@codemaskinc/store'
const { useStore } = createStore({
firstName: 'John',
lastName: 'Smith',
age: 30
})
const App = () => {
const {
state: { firstName, age },
actions: { setFirstName, setAge }
} = useStore('firstName', 'age')
return (
<div>
<p>Name: {firstName}</p>
<input
type="text"
value={firstName}
onChange={event => setFirstName(event.currentTarget.value)}
/>
<p>Age: {age}</p>
<input
type="number"
value={age}
onChange={event => setAge(event.currentTarget.value)}
/>
</div>
);
};
import { createScopedStore } from '@codemaskinc/store'
export const { StoreProvider, useScopedStore } = createScopedStore({
count: 0,
name: 'John'
})
// SSR Layout
<Layout>
<StoreProvider initialValue={{ name: await db.getUser().name }}>
{children}
</StoreProvider>
</Layout>
// Some client component inside layout
const scopedStore = useScopedStore()
const { state } = scopedStore.useStore('name')
return (
<h1>
Hello {state.name}
</h1>
)
import { createScopedStore } from '@codemaskinc/store'
export const { StoreProvider, useScopedStore } = createScopedStore({
count: 0,
name: 'John'
})
const ProfileScreen = withStore(() => {
// Component body...
})
// Some component inside ProfileScreen
const scopedStore = useScopedStore()
const { state } = scopedStore.useStore('name')
return (
<h1>
Hello {state.name}
</h1>
)
import { createStore, storage } from '@codemaskinc/store'
import { type CartItem } from 'lib/models'
const { useStore } = createStore({
counter: storage(0), // number
user: storage<string>(), // string | undefined
cart: [] as Array<CartItem>
})
FAQs
- ⚛️ updates outside react components - 🪝 easy access to all store values - ✍️ no repeating yourself - ⚡️ no unnecessary rerenders - 🚀 typescript intellisense
The npm package @codemaskinc/store receives a total of 10 weekly downloads. As such, @codemaskinc/store popularity was classified as not popular.
We found that @codemaskinc/store demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.