react-honey

Library that makes working with react state management a little sweeter

Usage no npm install needed!

<script type="module">
  import reactHoney from 'https://cdn.skypack.dev/react-honey';
</script>

README

🍯 React-Honey 🍯

A dev-friendly library that makes it a lot sweeter to work with global react state management 🥰

License CircleCI Open Issues Version

Installation

// With yarn
yarn add react-honey

// With npm
npm i react-honey

Quick Use Overview

import React from "react";
import ReactDOM from "react-dom";
import { addHoney, createHoneyStore, HoneyPot } from "react-honey";

// Create a state object with addHoney
const state = addHoney({
  name: "Bob Barker",
  age: 97,
  bestFriend: {
    name: "Happy Gilmore",
    age: 54,
  },
});

const App = () => {
  // Hook used to subscribe to state
  const { name, age } = state.useHoney("name", "age");

  return (
    <p>name: {name}</p>
    <p>age: {age}</p>
    <button onClick={() => state.set({ age: age + 1 })}>
      Increase
    </button>
  );
};

// Creates react-honey store
const store = createHoneyStore({ state });

ReactDOM.render(
  <HoneyPot store={store}>
    <App />
  <HoneyPot>,
  document.getElementById("root")
)

Take a deeper look at react-honey on the website. There's much more to this library, so sit tight! 🍿

Before Getting Started

There are many options that exist for global state management in React. What makes this library different is the ease at which you can work with state. While the store itself is global, addHoney creates self-contained objects that contain methods like state.useHoney, state.set, state.reset, and state.resetKey for subscribing to and updating state.

Behind the scenes, this library is just a wrapper around redux and react-redux. This was done in order to make it easy to create an easy-to-use library, while also maintaining the performance & reliability of a matured library like redux.

Initialize

Call createHoneyStore to initialize your store. Pass in an object of all of your created state objects.

Arguments

  • combinedState (required) - object - An object that contains all states returned from calling addHoney()

Returns

  • Honey store
import { createHoneyStore, addHoney, HoneyPot } from "react-honey";

// "addHoney" creates a new state object that can be added to "createHoneyStore"
const funWithReactHoney = addHoney({
  isFun: true,
  favFood: "pizza",
});

// Calling "createHoneyStore" creates your react-honey store
const store = createHoneyStore({ funWithReactHoney });

ReactDOM.render(
  <HoneyPot store={store}>
    <App />
  </HoneyPot>,
  document.getElementById("root")
);

addHoney(initialState)

Call addHoney(initialState) to create a new state object

Arguments

  • initialState (required) - object that defines the stucture of this piece of your store

Returns

  • state - (object) - an object containing the methods used to get, set, and reset this state object

Example:

import { addHoney } from "react-honey";

// addHoney() returns a self-contained object with five methods:
// state.useHoney(), state.set(), state.get(), state.resetKey(), and state.reset()
const state = addHoney({
  loveProgramming: false,
  favLibrary: "react-honey",
});

// exported to be added passed into the createHoneyStore method
export default state;

Typescript

There's also typescript generic support for typing your intialState and your state.set method calls

type State = {
  loveProgramming: boolean,
  favLibrary: string,
};

const state =
  addHoney <
  State >
  {
    loveProgramming: false,
    favLibrary: "react-honey",
    name: "Steve Smith", // Typescript will yell at ya for this!
  };

// Typescript will also get angry here because
// loveProgramming wasn't initially defined
state.set({ loveProgramming: "true" });

state

// React hook used for subscribing to state
state.useHoney();

// Updates state
state.set();

// Gets state object. Useful for accessing state without subscribing to it
state.get();

// Resets key back to its starting value set on initialState
state.resetKey();

// Reset back to the initialState that was passed in addHoney
state.reset();

state.useHoney(...keys)

Arguments

  • keys (required) - string - single or multiple strings that reference the values your component wants to subscribe to from the given state.

Returns

An object containing the values of the given keys

Example:

import { addHoney } from "react-honey";

const state = addHoney({
  isLiving: true,
  favLibrary: "react-honey",
  name: "Bob"
});

const App = () => {
  // subscribing to one key
  const { isLiving } = state.useHoney("isLiving");

  // subscribing to multiple keys
  const { isLiving, favLibrary, name } = state.useHoney("isLiving", "favLibrary", "name");

  return (
    ...
  )
}

state.set(payload)

Call state.set(payload) to update its state

Arguments

  • payload (required) - object - the key-value pairs that defines the changes you want to make to your state object.

Returns

null

Example:

import { addHoney } from "react-honey";

const state = addHoney({
  loveProgramming: false,
  favLibrary: "",
});

// updates state's favLibrary and loveProgramming
state.set({ favLibrary: "react-honey", loveProgramming: true });

Example with Typescript:

// Typescript = angry here because isGoingToFailToUpdate was
// not defined on the initialState
state.set({ favLibrary: "react-honey", isGoingToFailToUpdate: true });

state.get(key)

Call state.get(key) to retrieve what you need from its state.

Arguments

  • key (optional) - string - A key defined on the state.

Returns

  • Value(s) of the given key(s) in the state values
import { addHoney } from "react-honey";

const state = addHoney({
  name: "Bob",
  loveProgramming: false,
  favLibrary: "react-honey",
});

const favLibrary = state.get("favLibrary");

// Also accepts multiple arguments
const { loveProgramming, favLibrary } = state.get(
  "loveProgramming",
  "favLibrary"
);

// returns all state values if no arguments are given
const { name, loveProgramming, favLibrary } = state.get();

state.resetKey(key)

Arguments

  • key (required) - string - a key from your state you would like to reset back to its initial value

Returns

null

Call state.resetKey() to set a key's value back to its initialState that was passed when calling addHoney()

Example:

import { addHoney, nap } from "react-honey";

const state = addHoney({
  isLoading: false,
  name: "Bob",
  details: {},
});

state.set({ name: "Henry" });

// resets name back to "Bob"
state.resetKey("name");

state.reset(options)

Arguments

  • options (optional) - object - a set of options when calling state.reset(). Options are defined below.

Returns

null

Call state.reset() to set the state back to the passed initialState.

Example:

import { addHoney, nap } from "react-honey";

const state = addHoney({
  isLoading: false,
  isSaving: false,
  name: "Bob",
});

state.set({ isLoading: true, isSaving: true, name: "Steve" });

// Resets all key-value pairs back to original value
state.reset();

Super simple!

Options (state.reset())

keepKeyValues - (optional) - array - This allows you to call state.reset() but keep current values of certain keys.

const state = addHoney({
  isLoading: false,
  isSaving: false,
  favLibrary: "react-honey",
  name: "Bob Barker",
});

state.set({ name: "Steve Smith", isLoading: true, favLibrary: "" });

// resets state back to its initialState except for "name"
state.reset({ keepKeyValues: ["name"] });

nap(duration)

Call nap() when you need to block code execution for a defined duration.

Arguments

  • duration (required) - number - the number of ms you want to wait until continuing

Returns

Promise

Example:

await nap(500);

store.reset()

Arguments

none

Returns

null

Call store.reset() when you need to reset all states in your store back to its initialState. A use case for this would be after a user signs out of a SPA.

Example:

import { addHoney, nap } from "react-honey";

const user = addHoney({
  name: "Steve Smith",
  age: 99,
});

const details = addHoney({
  page: "/random",
  friends: [],
});

const store = createHoneyPot({ user, details });

user.set({ name: "Bob" });
details.set({ page: "/not-as-random" });

// Resets entire store back to all passed initialStates
store.reset();

License

The MIT License (MIT)

Copyright (c) 2019-present Kody Rouse

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.