# react-simmor

> React bindings for Simmor

Latest version **0.3.0** (published 2019-10-09) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-simmor
pnpm add react-simmor
yarn add react-simmor
bun add react-simmor
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.3.0 |
| Published | 2019-10-09 |
| First published | 2019-09-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 30.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | ptol |
| Maintainers | ptol |
| Keywords | TypeScript, react, store |

## Links

- npm: https://www.npmjs.com/package/react-simmor
- Repository: https://github.com/simmor-store/react-simmor
- Homepage: https://github.com/simmor-store/react-simmor#readme
- Issues: https://github.com/simmor-store/react-simmor/issues
- npm.io page: https://npm.io/package/react-simmor

## Dependencies (1)

- [proxyequal](https://npm.io/package/proxyequal.md) ^2.1.1

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.3.0 (latest) — 2019-10-09
- 0.2.4 — 2019-10-06
- 0.2.3 — 2019-09-29
- 0.2.2 — 2019-09-29
- 0.2.1 — 2019-09-29

## README

Simmor is a simple immutable boilerplate-free framework-agnostic store.

[https://github.com/simmor-store/simmor](https://github.com/simmor-store/simmor) 


# Install

`npm install simmor react-simmor`

# Online demo

[https://codesandbox.io/s/github/simmor-store/react-simmor/tree/master/examples](https://codesandbox.io/s/github/simmor-store/react-simmor/tree/master/examples)

# Examples

The simplest way to use simmor is by creating a localStore.

```ts
  const [state, dispatch] = useLocalStore({value: 0}, ctx => ({
    increase() {
      ctx.draft.value += 1
    },
    decrease() {
      const newValue = ctx.draft.value - 1
      if (newValue >= 0) {
        ctx.draft.value = newValue
      }
    },
    increaseWithDelay() {
      setTimeout(() => this.increase(), 300)
    },   
    setValue(value: number) {
      ctx.draft.value = value
    }
  }))

```
```ts
    <div className="counter">
      <span>{state.value}</span>
      <button onClick={() => dispatch.increase()}>+</button>
      <button onClick={() => dispatch.decrease()}>-</button>
      <button onClick={() => dispatch.setValue(0)}>reset</button>
      <button onClick={() => dispatch.increaseWithDelay()}>Increase with delay</button>
    </div>

```

# Store class
It's possible to create store as class

```ts
export type CounterState = { value: number }

export class CounterStore extends ReducerStore<CounterState> {

  increase() {
    this.draft.value += 1
  }

  decrease() {
    const newValue = this.draft.value - 1
    if (newValue >= 0) {
      this.draft.value = newValue
    }
  }

  setValue(value: number) {
    this.draft.value = value
  }
}

```

```ts
export const Counter = ({store}: { store: CounterStore }) => {
  const value = useStore(store, x => x.value)
  return (
    <div className="counter"><span>{value}</span>
      <button onClick={() => store.increase()}>+</button>
      <button onClick={() => store.decrease()}>-</button>
      <button onClick={() => store.setValue(0)}>Reset</button>
    </div>
  )
}

```
```ts
const store = new CounterStore({value: 0})
<Counter store={store}/>
```

# Middleware
An example of middleware that saves state to localStorage.
```ts
export function createLocalStorageMiddleware(name: string): Middleware {
  return next => action => {
    const result = next(action)
    if (action.methodName === "constructor") {
      const savedState = localStorage.getItem(name)
      if (savedState) {
        action.context.rxState.setState(JSON.parse(savedState))
      }
    }
    localStorage.setItem(name, JSON.stringify(action.context.rxState.state))
    return result
  }
}
```

```ts
const persistentStore = new CounterStore({value: 0}, {
    middlewares: [createLocalStorageMiddleware('counter')]
})

<Counter store={persistentStore}/>
```

# State slicing
It is possible to slice a part of the state.
For example if we need two counters and we want to swap values between them.

```ts

type CounterPairState = {
  left: CounterState
  right: CounterState
}

export class CounterPairStore extends ReducerStore<CounterPairState> {
  leftStore = new CounterStore(this.rxState.slice('left'))
  rightStore = new CounterStore(this.rxState.slice('right'))

  constructor() {
    super({left: {value: 100}, right: {value: 200}})
  }

  swap() {
    const [leftValue, rightValue] = [this.state.left.value, this.state.right.value]
    this.leftStore.setValue(rightValue)
    this.rightStore.setValue(leftValue)
  }

  static sum(state: CounterPairState) {
    return state.left.value + state.right.value
  }
}

```
```ts
const store = new CounterPairStore()
export const CounterPair = () => {
  const state = useStore(store, x => x)
  const sum = CounterPairStore.sum(state)

  return (
    <div className="pair">
      <div>
        <button onClick={() => store.swap()}>swap</button>
        <span>Sum {sum}</span>
      </div>
      <Counter store={store.leftStore}/>
      <Counter store={store.rightStore}/>
    </div>
  )

}
```

---
_Source: https://npm.io/package/react-simmor · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
