All Projects → yamalight → Outstated

yamalight / Outstated

Simple hooks-based state management for React

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Outstated

react-cool-form
😎 📋 React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (+141.18%)
Mutual labels:  hooks, state
Iostore
极简的全局数据管理方案,基于 React Hooks API
Stars: ✭ 99 (-2.94%)
Mutual labels:  hooks, state
teaful
🍵 Tiny, easy and powerful React state management
Stars: ✭ 638 (+525.49%)
Mutual labels:  management, state
Stencil Store
Store is a lightweight shared state library by the StencilJS core team. Implements a simple key/value map that efficiently re-renders components when necessary.
Stars: ✭ 107 (+4.9%)
Mutual labels:  management, state
Pullstate
Simple state stores using immer and React hooks - re-use parts of your state by pulling it anywhere you like!
Stars: ✭ 683 (+569.61%)
Mutual labels:  hooks, state
Store
A beautifully-simple framework-agnostic modern state management library.
Stars: ✭ 204 (+100%)
Mutual labels:  management, state
eventrix
Open-source, Predictable, Scaling JavaScript library for state managing and centralizing application global state. State manage system for react apps.
Stars: ✭ 35 (-65.69%)
Mutual labels:  hooks, state
Pure Store
A tiny immutable store with type safety.
Stars: ✭ 133 (+30.39%)
Mutual labels:  hooks, state
Statty
A tiny and unobtrusive state management library for React and Preact apps
Stars: ✭ 516 (+405.88%)
Mutual labels:  management, state
Jotai
👻 Primitive and flexible state management for React
Stars: ✭ 6,453 (+6226.47%)
Mutual labels:  management, state
Flooks
🍸 A state manager for React Hooks
Stars: ✭ 201 (+97.06%)
Mutual labels:  hooks, state
Use Global Context
A new way to use “useContext” better
Stars: ✭ 34 (-66.67%)
Mutual labels:  hooks, state
Simpler State
The simplest app state management for React
Stars: ✭ 68 (-33.33%)
Mutual labels:  hooks, state
useSharedState
useSharedState is a simple hook that can be used to share state between multiple React components.
Stars: ✭ 0 (-100%)
Mutual labels:  hooks, state
Fielder
A field-first form library for React and React Native
Stars: ✭ 160 (+56.86%)
Mutual labels:  hooks, state
jedisdb
redis like key-value state management solution for React
Stars: ✭ 13 (-87.25%)
Mutual labels:  hooks, state
Clean State
🐻 A pure and compact state manager, using React-hooks native implementation, automatically connect the module organization architecture. 🍋
Stars: ✭ 107 (+4.9%)
Mutual labels:  hooks, state
atomic-state
A decentralized state management library for React
Stars: ✭ 54 (-47.06%)
Mutual labels:  hooks, state
Tng Hooks
Provides React-inspired 'hooks' like useState(..) for stand-alone functions
Stars: ✭ 954 (+835.29%)
Mutual labels:  hooks, state
Unstated
State so simple, it goes without saying
Stars: ✭ 7,785 (+7532.35%)
Mutual labels:  management, state

Outstated

Simple hooks-based state management for React

Build Status Coverage Status Minzip Size license

Like unstated but with hooks

Installation

npm install outstated

Example

import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import {Provider, useStore} from 'outstated';

const store = () => {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
  const reset = () => setCount(0);

  return {count, increment, decrement, reset};
};

function Counter() {
  const {count, increment, decrement, reset} = useStore(store);

  return (
    <div>
      <button onClick={decrement}>-</button>
      <span>{count}</span>
      <button onClick={increment}>+</button>
      <button onClick={reset}>reset</button>
    </div>
  );
}

ReactDOM.render(
  <Provider stores={[store]}>
    <Counter />
  </Provider>,
  document.getElementById('root')
);

For more examples, see the example/ directory.

Guide

Unstated is awesome, but doesn't really use hooks.
Can we build something similar to unstated with hooks to make something even nicer?

Introducing Outstated

I really like unstated. I really like hooks. I wanted a simple hook-based app state management solution. This is why I've built Outstated.

Outstated is built on top of React hooks, context and patterns surrounding those elements.

It has three pieces:

Store

It's a place to store our state and some of the logic for updating it.

Store is a very simple React hook (which means you can re-use it, use other hooks within it, etc).

import {useState} from 'React';

const store = () => {
  const [state, setState] = useState({test: true});

  const update = val => setState(val);

  return {state, update};
};

Note that stores use useState hook from React for managing state. When you call setState it triggers components to re-render, so be careful not to mutate state directly or your components won't re-render.

useStore

Next we'll need a piece to introduce our state back into the tree so that:

  • When state changes, our components re-render.
  • We can depend on our store state.
  • We can call functions exposed by the store.

For this we have the useStore hook which allows us to get global store instances by using specific store constructor.

function Counter() {
  const {count, decrement, increment} = useStore(counterStore);

  return (
    <div>
      <span>{count}</span>
      <button onClick={decrement}>-</button>
      <button onClick={increment}>+</button>
    </div>
  );
}
<Provider>

The final piece that Outstated has is <Provider> component. It has two roles:

  1. It initializes global instances of given stores (this is required because React expects the number of hooks to be consistent across re-renders)
  2. It uses a set of contexts to pass initialized instances of given stores to all the components down the tree.
    Different context is used for each store. This allows to only trigger re-renders in the components that use the updated store. As a (minor) downside of this approach - nested contexts are created for each store you pass.
render(
  <Provider stores={[counterStore]}>
    <Counter />
  </Provider>
);

Testing

Whenever we consider the way that we write the state in our apps we should be thinking about testing.
We want to make sure that our state containers have a clean way to test them.

Because our containers are just hooks, we can construct them in tests and assert different things about them very easily.

import {renderHook, act} from 'react-hooks-testing-library';

test('counter', async () => {
  let count, increment, decrement;
  renderHook(() => ({count, increment, decrement} = counterStore()));

  expect(count).toBe(0);

  act(() => increment());
  expect(count).toBe(1);

  act(() => decrement());
  expect(count).toBe(0);
});

Related

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].