DEV Community

Cover image for Easy global state in React which can be used outside React components too
Richard Lindhout
Richard Lindhout

Posted on • Edited on

Easy global state in React which can be used outside React components too

Github: https://github.com/web-ridge/react-ridge-state

react-ridge-state ๐Ÿ‹๏ธโ€โ™€๏ธ โšก๏ธ ๐Ÿ‹๏ธโ€โ™‚๏ธ

Simple ๐Ÿ’ช fast โšก๏ธ and small ๐ŸŽˆ (500 bytes) global state management for React which can be used outside of a React component too!

yarn add react-ridge-state

or

npm install react-ridge-state --save

Why another state library ๐Ÿค”

We were frustrated that the current solutions could often only be used from React or have too complicated APIs. We wanted a lightweight solution with a smart API that can also be used outside React components.

Features ๐Ÿคนโ€โ™€๏ธ

  • React / React Native
  • Simple
  • Fast
  • Very tiny (500 bytes)
  • 100% Typesafe
  • Hooks
  • Use outside React components

Roadmap ๐Ÿƒโ€โ™€๏ธ ๐Ÿƒโ€โ™‚๏ธ

  • Custom selectors for deep state selecting

Getting started ๐Ÿ‘ ๐Ÿ‘Œ

Create a new state

import { newRidgeState } from "react-ridge-state";
interface CartProduct {
  id: number;
  name: string;
}
export const cartProductsState = newRidgeState<CartProduct[]>([
  { id: 1, name: "Product" },
]);

Use state inside components

import { cartProductsState } from "../cartProductsStatee";

const [cartProducts, setCartProducts] = cartProductsState.use();

Use state outside of React

import { cartProductsState } from "../cartProductsStatee";
cartProductsState.get();

Set state outside of React

import { cartProductsState } from "../cartProductsStatee";

// simple and direct
cartProductsState.set([{ id: 1, name: "NiceProduct" }]);

// if you want previous state as callback
cartProductsState.set((prevState) => [
  ...prevState,
  { id: 1, name: "NiceProduct" },
]);

// you can also use a callback so you know when state has rendered
cartProductsState.set(
  (prevState) => [...prevState, { id: 1, name: "NiceProduct" }],
  (newState) => {
    console.log("New state is rendered everywhere");
  }
);

Counter example

import { newRidgeState } from "react-ridge-state";

// this can be used everywhere in your application
export const globalCounterState = newRidgeState<number>(0);

function CounterComponent() {
  const [count, setCount] = globalCounterState.use();
  return (
    <div>
      <div>Count: {count}</div>
      <button onClick={() => setCount(c + 1)}>Add 1</button>
    </div>
  );
}

// you can use these everywhere in your application the globalCounterState will update automatically
// even if set globally
function CounterViewer() {
  const count = globalCounterState.useValue();

  return (
    <div>
      <div>Count: {count}</div>
    </div>
  );
}

Persistence example

It's possible to add persistency to your state. (add try/catch if you use localStorage in real app)

const authStorageKey = "auth";
const authState = newRidgeState<AuthState>(
  getInitialState() || emptyAuthState,
  { onSet }
);

// getInitialState fetches data from localStorage
function getInitialState() {
  let initialState = undefined;
  const item = localStorage.getItem(authStorageKey);
  if (item) {
    initialState = JSON.parse(item);
  }
}

// onSet is called after state has been set
function onSet() {
  // save to local storage
  localStorage.setItem(authStorageKey, JSON.stringify(newState));
}

About us

We want developers to be able to build software faster using modern tools like GraphQL, Golang, React Native without depending on commercial providers like Firebase or AWS Amplify.

Checkout our other products too! ๐Ÿ‘Œ https://github.com/web-ridge

Top comments (0)