Skip to content
This repository has been archived by the owner on Mar 15, 2023. It is now read-only.

Commit

Permalink
✨ Adding props capability to createStore
Browse files Browse the repository at this point in the history
  • Loading branch information
amoutonbrady committed Dec 20, 2020
1 parent 4cc84b1 commit 3339e8c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ The ultimate companion of all your [solid-js](https://github.com/ryansolid/solid
- [Basic usage](#basic-usage)
- [With providers](#with-providers)
- [With disposable app](#with-disposable-app)
- [createProvider](#createprovider)
- [createStore](#createstore)
- [Basic usage](#basic-usage-1)
- [With props](#with-props)

## Features

Expand Down Expand Up @@ -99,14 +100,14 @@ if (module.hot) {
}
```

### createProvider
### createStore

A small utility that helps generate Provider & associated hook

#### Basic usage

```tsx
const [Provider, useProvider] = createProvider(
const [Provider, useProvider] = createStore(
{ count: 0, first: 'Alexandre' },
(set, get) => ({
increment(by = 1) {
Expand All @@ -129,4 +130,33 @@ const Counter = () => {
}

render(() => <Provider><Counter /><Counter /></Provider>, document.getElementById('app'))
```

#### With props

```tsx
const [Provider, useProvider] = createStore<{ count: number }>(
(props) => ({ count: props.count, first: 'Alexandre' }),

(set, get) => ({
increment(by = 1) {
set('count', count => count + 1)
},
dynamicFullName(last) {
return `${get.first} ${last} ${get.count}`;
}
})
)

const Counter = () => {
const [state, { increment, dynamicFullName }] = useProvider()

// The count here will be synced between the two <Counter /> because it's global
return <>
<button onClick={[increment, 1]}>{state.count}</button>
<h1>{dynamicFullName('Mouton-Brady')}</h1>
</>
}

render(() => <Provider count={2}><Counter /><Counter /></Provider>, document.getElementById('app'))
```
17 changes: 12 additions & 5 deletions src/createStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ interface CreateStoreFn<A, B, C = B & { set: SetStateFunction<A> }> {
(store: A, fn: (set: SetStateFunction<A>, get: State<A>) => B): readonly [State<A>, C];
}

function generateStore<A, B>(store: A, fn: (set: SetStateFunction<A>, get: State<A>) => B) {
const [get, set] = createState(store);
type CommonObject = Record<string, any>;

function generateStore<A, B, C>(
store: A,
fn: (set: SetStateFunction<A>, get: State<A>) => B,
props?: C,
) {
const finalStore: A = typeof store === 'function' ? store(props) : store;
const [get, set] = createState(finalStore);

return [get, { ...fn(set, get), set }] as const;
}
Expand Down Expand Up @@ -45,15 +52,15 @@ function generateStore<A, B>(store: A, fn: (set: SetStateFunction<A>, get: State
* app.mount('#app')
* ```
*/
export function createStore<T extends Record<string, any>, B>(
export function createStore<P extends CommonObject, T extends CommonObject, B>(
store: T,
fn: (set: SetStateFunction<T>, get: State<T>) => B,
) {
type Store = ReturnType<CreateStoreFn<T, B>>;
const Context = createContext<Store>();

const Provider: Component = (props) => {
const value: Store = generateStore(store, fn);
const Provider: Component<P> = (props) => {
const value: Store = generateStore(store, fn, props);

return <Context.Provider value={value}>{props.children}</Context.Provider>;
};
Expand Down

0 comments on commit 3339e8c

Please sign in to comment.