# react-charm

> Effortless state management

Latest version **1.0.26** (published 2019-07-14) · ISC license · 0 weekly downloads

## Install

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

## Health

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

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.26 |
| Published | 2019-07-14 |
| First published | 2019-07-07 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 89.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 3 |
| Maintainers | linq2js |
| Keywords | react, redux, state management, state manager, state, manager, store, flux |

## Links

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

## Dependencies (1)

- [immer](https://npm.io/package/immer.md) ^3.1.3

## Alternatives

- [@reckona/mreact-store](https://npm.io/package/@reckona/mreact-store.md) — 976 weekly downloads
- [regular-state](https://npm.io/package/regular-state.md) — 410 weekly downloads
- [@pacote/flux-actions](https://npm.io/package/@pacote/flux-actions.md) — 65 weekly downloads
- [@pilotlab/lux-debug](https://npm.io/package/@pilotlab/lux-debug.md) — 39 weekly downloads
- [vue-persist-state](https://npm.io/package/vue-persist-state.md) — 19 weekly downloads

## Recent versions

- 1.0.26 (latest) — 2019-07-14
- 1.0.25 — 2019-07-13
- 1.0.24 — 2019-07-13
- 1.0.23 — 2019-07-13
- 1.0.21 — 2019-07-12
- 1.0.20 — 2019-07-12
- 1.0.19 — 2019-07-12
- 1.0.18 — 2019-07-12
- 1.0.17 — 2019-07-11
- 1.0.16 — 2019-07-11
- 1.0.15 — 2019-07-11
- 1.0.14 — 2019-07-11
- 1.0.12 — 2019-07-11
- 1.0.11 — 2019-07-11
- 1.0.10 — 2019-07-10
- … 9 more at https://npm.io/package/react-charm/versions

## README

# react-charm

## Counter App

```jsx harmony
import React from "react";
import { render } from "react-dom";
import { useStates, setState, dispatch } from "react-charm";

setState({ counter: 0 });

// create named action
const increase = ({ state }) => state.counter++;

const App = () => {
  // useCharm retrieves state selector list
  // then return array of [stateValue1, stateValue2, ...]
  const [counter] = useStates(state => state.counter);

  function handleClick() {
    dispatch(increase);
  }

  return (
    <>
      <h1>{counter}</h1>
      <button onClick={handleClick}>Increase</button>
    </>
  );
};

render(<App />, document.getElementById("root"));
```

## Ajax Data Loading

```jsx harmony
import React from "react";
import { render } from "react-dom";
import { useStates, dispatch } from "react-charm";

const fetchEffect = ({ action }, url, onSuccess, onFailure) => {
  fetch(url)
    .then(res => res.json())
    .then(payload => {
      payload.message
        ? action(onFailure, payload.message)
        : action(onSuccess, payload);
    });
};

const loadDataSuccessAction = ({ state }, payload) => {
  state.loading = false;
  state.data = payload;
};

const loadDataFailureAction = ({ state }, error) => {
  state.loading = false;
  state.error = error;
};

const loadDataAction = ({ state, effect }, url) => {
  state.loading = true;
  delete state.error;
  delete state.data;
  effect(fetchEffect, url, loadDataSuccessAction, loadDataFailureAction);
};

const validUrl = "https://api.myjson.com/bins/vrtvf";
const invalidUrl = "https://api.myjson.com/bins/invalid";

const App = () => {
  const [data, error, loading] = useStates("data", "error", "loading");

  function handleClickSuccess() {
    dispatch(loadDataAction, validUrl);
  }

  function handleClickFailure() {
    dispatch(loadDataAction, invalidUrl);
  }

  return (
    <>
      {!loading && (
        <>
          <button onClick={handleClickSuccess}>Load Data Success</button>{" "}
          <button onClick={handleClickFailure}>Load Data Failure</button>
        </>
      )}
      <pre>
        {typeof loading === "boolean" ? (
          loading ? (
            "Loading..."
          ) : error ? (
            <span style={{ color: "red" }}>{error}</span>
          ) : (
            JSON.stringify(data, null, 2)
          )
        ) : (
          ""
        )}
      </pre>
    </>
  );
};

render(<App />, document.getElementById("root"));
```

## Handling action dispatching

Sometimes you want to listen when specified action is dispatched then do something

```jsx harmony
import { on } from "react-charm";
// module user-management
const SignOutAction = ({ state }) => delete state.accessToken;

// module product
// we should dispose all product state props
on(SignOutAction, ({ state }) => delete state.productList);
```

## Watching state props changes

```jsx harmony
import { watch } from "react-charm";

watch(
  state => state.counter,
  ({ state }) => {
    console.log("counter changed", state.counter);

    // even you can mutate state
    // watcher will not be called recursively
    state.counter++;
  }
);

setState({
  counter: 1
});
```

## API

### setState(nextState:Object)

### getState():Object

### initState(initialState:Object)

### subscribe(subscriber:Function)

### on(action:Function, stateMutator:Function):Function

### on(actions:Function[], stateMutator:Function):Function

### on(\[\[action1:Function, stateMutator1:Function], \[action2:Function, stateMutator2:Function], ...]):Function

### dispatch(action:Function, ....args:Object[])

### useStates(...stateSelector:FunctionOrString[]):Object[]

### useActions(...actions:Function[])

### withStates(stateMap:Object):Function

### withActions(actionMap:Object):Function

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