# @sethwebster/simple-state

> A simple state management library for React

Latest version **0.0.7** (published 2023-01-11) · ISC license · 0 weekly downloads

## Install

```sh
npm install @sethwebster/simple-state
pnpm add @sethwebster/simple-state
yarn add @sethwebster/simple-state
bun add @sethwebster/simple-state
```

## Health

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

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

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.7 |
| Published | 2023-01-11 |
| First published | 2023-01-04 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 5 |
| Unpacked size | 38.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Seth Webster |
| Maintainers | sethwebster |
| Keywords | react, state, state management, global |

## Links

- npm: https://www.npmjs.com/package/@sethwebster/simple-state
- Repository: https://github.com/sethwebster/simple-state
- Issues: https://github.com/sethwebster/simple-state/issues
- npm.io page: https://npm.io/package/@sethwebster/simple-state

## Dependencies (5)

- [react](https://npm.io/package/react.md) ^18.1.0
- [typescript](https://npm.io/package/typescript.md) ^4.9.4
- [async-mutex](https://npm.io/package/async-mutex.md) ^0.4.0
- [tiny-invariant](https://npm.io/package/tiny-invariant.md) ^1.3.1
- [double-ended-queue](https://npm.io/package/double-ended-queue.md) ^2.1.0-0

## 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.0.7 (latest) — 2023-01-11
- 0.0.6 — 2023-01-11
- 0.0.5 — 2023-01-11
- 0.0.4 — 2023-01-11
- 0.0.3 — 2023-01-11
- 0.0.2 — 2023-01-08
- 0.0.1-12 — 2023-01-06
- 0.0.1-10 — 2023-01-06
- 0.0.1-9 — 2023-01-05
- 0.0.1-8 — 2023-01-05
- 0.0.1-7 — 2023-01-05
- 0.0.1-5 — 2023-01-05
- 0.0.1-4 — 2023-01-05
- 0.0.1-3 — 2023-01-05
- 0.0.1-2 — 2023-01-04
- … 2 more at https://npm.io/package/@sethwebster/simple-state/versions

## README

# React Simple State 

Simple, global, high-performance state management for React.

```jsx
...
import {useQuark} from '@sethwebster/simple-state';

function ComponentA() {
  const [ value, useQuark ] = useQuark('some-thing', 0);

  return (
    <div>
      <p>Value: {value}</p>
    </div>
  )
}

function ComponentB() {
  // Default value is ignored when declared a second time
  const [ value, useQuark ] = useQuark('some-thing', 0);

  return (
    <div>
      <p>Value: {value}</p>
      <button onClick={() => useQuark(value + 1)}>Increment</button>
    </div>
  )
}
...
```

## Installation

```bash
npm i @sethwebster/simple-state
```

## Usage

There are two primary apis:

- `useQuark` - A hook that returns a value and a setter function
- `useDerivedQuark` - A hook that returns a derived value based on other quark(s).

State is shared globally, but you can segment your data by using a context, `<SimpleStateRoot>`. This is useful if your data model organized in such a way that some is global to the whole app, and some is shared amongst a sub-section.

```jsx
import { SimpleStateRoot } from '@sethwebster/simple-state';

function Products() {
  const products = getProducts();
  const [selectedProduct, setSelectedProduct] = useQuark('selected-product', products[0]);

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>
          <button onClick={() => setSelectedProduct(product)}>{product.name}</button>
        </li>
      ))}
    </ul>
  )
}

function Nav() {
  const [selectedTab, setSelectedTab] = useQuark("selected-tab", "products");
}

function App() {
  return (
    {/* The state here is separate from that state within the <SimpleStateRoot /> below */}
    <Header>
      <Nav selectedTab={selectedTab} />
    </Header>
    {/* new state context */}
    <SimpleStateRoot>
      <Products />
    </SimpleStateRoot>
  )
}
```

## API
### useQuark 

```js
const [value, setValue] = useQuark<T>(key: string, initialValue: T): [T, (newValue: T) => void]
```

This hook is strongly typed and returns a value and a setter function. The setter function is memoized, so it can be passed to child components without causing unnecessary re-renders if desired. However, this is not strictly necessary as it's all the same shared state.


<table>
    <tr>
      <th>parameter</th>
      <th>type</th>
      <th>notes</th>
    </tr>
  <tbody>
  <tr>
    <td>      
      T
    </td>
    <td>
      type
    </td>
    <td>
        (optional) Supply the type of data to store
    </td>
  </tr>
  <tr>
    <td>
      key  
    </td>
    <td>
      string
    </td>
    <td>
      Supply the globally unique key for this data. Any other invocations of `useQuark` will refer to the same state, and return the same value.
    </td>
  </tr>
  <tr>
    <td>
      <code>
        initialValue  
      </code> 
    </td>
    <td>
        (optional) T
    </td>
    <td>
      The inital value to store.
    </td>
  </tr>
  </tbody>
</table>

### useDerivedQuark 

```js
const value = useDerivedQuark<T>(
   key: string, 
   selector: (({get: (key: string): ?}) => T)
): T
```

This hook is strongly typed and returns a value derived using the selector function.

```jsx
import { useQuark, useDerivedQuark } from '@sethwebster/simples-state';

function ComponentA() {
  const [value, setValue] = useQuark('some-thing', 10);
  const [otherValue, setOtherValue] = useQuark('some-other-thing', 15);

  // Update the values in some way
  useEffect(()=>{
    const interval = setInterval(() => {
      setValue(value + 5);
      setOtherValue(otherValue + 10);
    }, 1000)
  },[]);

  ...
}

function DerivedComponentB() {
  const value = useDerivedQuark('some-key-derived', ({get}) => {

    // Run when either value changes, and this component re-renders
    const someThing = get<number>('some-thing');
    const someOtherThing = get<number>('some-other-thing');

    return someThing * someOtherThing;
  })  
  
  return <div>{value}</div>
}
// 0s
// <div>150</div>
// 1s
// <div>375</div>
...
```


<table>
  <tr>
    <th>parameter</th>
    <th>type</th>
    <th>notes</th>
  </tr>
  <tr>
    <td>      
      T
    </td>
    <td>
      (optional) return type
    </td>
    <td>
        (optional) Supply the type of data to return
    </td>
  </tr>
  <tr>
    <td>
      key  
    </td>
    <td>
      string
    </td>
    <td>
      Supply the globally unique key for this derived data. Any other invocations of `useDerivedQuark` will refer to the same item, and will <em>not</em> overwrite the selector.
    </td>
  </tr>
<tr>
<td>
selector  
</td>
  <td>

  ```js
  <TReturn>({get<T>: (key: string) => T}) => TReturn
  ```
  </td> 
  <td>
    A selector. This selector is called with a `get` function that can be used to retrieve other quarks. When a quark is retrieved, the selector will be re-run when that quark changes. The selector should return a value of type `TReturn`.
  </td>
</tr>
</table>

License: [MIT](./LICENSE.txt)

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