All Projects → diegohaz → Constate

diegohaz / Constate

Licence: mit
React Context + State

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Constate

React-Combine-Provider
combine react providers in ease
Stars: ✭ 29 (-99.18%)
Mutual labels:  hooks, react-state, react-context, constate, react-hooks
Easy Peasy
Vegetarian friendly state for React
Stars: ✭ 4,525 (+28.59%)
Mutual labels:  hooks, state-management, react-hooks
resynced
An experimental hook that lets you have multiple components using multiple synced states using no context provider
Stars: ✭ 19 (-99.46%)
Mutual labels:  hooks, state-management, react-hooks
niue
A tiny shared state and event library for React
Stars: ✭ 17 (-99.52%)
Mutual labels:  state-management, react-state, react-hooks
atomic-state
A decentralized state management library for React
Stars: ✭ 54 (-98.47%)
Mutual labels:  hooks, state-management, react-hooks
use-app-state
🌏 useAppState() hook. that global version of setState() built on Context.
Stars: ✭ 65 (-98.15%)
Mutual labels:  hooks, state-management, react-hooks
react-cool-form
😎 📋 React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (-93.01%)
Mutual labels:  hooks, state-management, react-hooks
use-query-string
🆙 A React hook that serializes state into the URL query string
Stars: ✭ 50 (-98.58%)
Mutual labels:  hooks, state-management, react-hooks
jedisdb
redis like key-value state management solution for React
Stars: ✭ 13 (-99.63%)
Mutual labels:  hooks, state-management, react-hooks
Radioactive State
☢ Make Your React App Truly Reactive!
Stars: ✭ 273 (-92.24%)
Mutual labels:  hooks, state-management
reason-hooks-lib
A set of reusable ReasonReact hooks.
Stars: ✭ 31 (-99.12%)
Mutual labels:  hooks, react-hooks
react-abac
Attribute Based Access Control for React
Stars: ✭ 54 (-98.47%)
Mutual labels:  react-context, react-hooks
max-todos
A basic Todo app developed in React.
Stars: ✭ 19 (-99.46%)
Mutual labels:  hooks, react-hooks
use-window-focus
React Hook to check if window is focused
Stars: ✭ 19 (-99.46%)
Mutual labels:  hooks, react-hooks
react-daterange-picker
A react date range picker to using @material-ui. Live Demo: https://flippingbitss.github.io/react-daterange-picker/
Stars: ✭ 85 (-97.58%)
Mutual labels:  hooks, react-hooks
use-metamask
a custom React Hook to manage Metamask in Ethereum ĐApp projects
Stars: ✭ 131 (-96.28%)
Mutual labels:  hooks, react-hooks
react-smart-app
Preconfiguration React + Ant Design + State Management
Stars: ✭ 13 (-99.63%)
Mutual labels:  hooks, state-management
learn-react-typescript
Learning React contents with TypeScript (Hooks, Redux)
Stars: ✭ 15 (-99.57%)
Mutual labels:  hooks, react-hooks
useAudioPlayer
Custom React hook & context for controlling browser audio
Stars: ✭ 176 (-95%)
Mutual labels:  hooks, react-hooks
react-europe-2019
Slides and demo app from my keynote
Stars: ✭ 29 (-99.18%)
Mutual labels:  hooks, react-hooks

constate logo

Constate

NPM version NPM downloads Size Dependencies Build Status Coverage Status

Write local state using React Hooks and lift it up to React Context only when needed with minimum effort.


🕹 CodeSandbox demos 🕹
Counter I18n Theming TypeScript Wizard Form

Basic example

import React, { useState } from "react";
import constate from "constate";

// 1️⃣ Create a custom hook as usual
function useCounter() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(prevCount => prevCount + 1);
  return { count, increment };
}

// 2️⃣ Wrap your hook with the constate factory
const [CounterProvider, useCounterContext] = constate(useCounter);

function Button() {
  // 3️⃣ Use context instead of custom hook
  const { increment } = useCounterContext();
  return <button onClick={increment}>+</button>;
}

function Count() {
  // 4️⃣ Use context in other components
  const { count } = useCounterContext();
  return <span>{count}</span>;
}

function App() {
  // 5️⃣ Wrap your components with Provider
  return (
    <CounterProvider>
      <Count />
      <Button />
    </CounterProvider>
  );
}

Learn more

Advanced example

import React, { useState, useCallback } from "react";
import constate from "constate";

// 1️⃣ Create a custom hook that receives props
function useCounter({ initialCount = 0 }) {
  const [count, setCount] = useState(initialCount);
  // 2️⃣ Wrap your updaters with useCallback or use dispatch from useReducer
  const increment = useCallback(() => setCount(prev => prev + 1), []);
  return { count, increment };
}

// 3️⃣ Wrap your hook with the constate factory splitting the values
const [CounterProvider, useCount, useIncrement] = constate(
  useCounter,
  value => value.count, // becomes useCount
  value => value.increment // becomes useIncrement
);

function Button() {
  // 4️⃣ Use the updater context that will never trigger a re-render
  const increment = useIncrement();
  return <button onClick={increment}>+</button>;
}

function Count() {
  // 5️⃣ Use the state context in other components
  const count = useCount();
  return <span>{count}</span>;
}

function App() {
  // 6️⃣ Wrap your components with Provider passing props to your hook
  return (
    <CounterProvider initialCount={10}>
      <Count />
      <Button />
    </CounterProvider>
  );
}

Learn more

Installation

npm:

npm i constate

Yarn:

yarn add constate

API

constate(useValue[, ...selectors])

Constate exports a single factory method. As parameters, it receives useValue and optional selector functions. It returns a tuple of [Provider, ...hooks].

useValue

It's any custom hook:

import { useState } from "react";
import constate from "constate";

const [CountProvider, useCountContext] = constate(() => {
  const [count] = useState(0);
  return count;
});

You can receive props in the custom hook function. They will be populated with <Provider />:

const [CountProvider, useCountContext] = constate(({ initialCount = 0 }) => {
  const [count] = useState(initialCount);
  return count;
});

function App() {
  return (
    <CountProvider initialCount={10}>
      ...
    </CountProvider>
  );
}

The API of the containerized hook returns the same value(s) as the original, as long as it is a descendant of the Provider:

function Count() {
  const count = useCountContext();
  console.log(count); // 10
}

selectors

Optionally, you can pass in one or more functions to split the custom hook value into multiple React Contexts. This is useful so you can avoid unnecessary re-renders on components that only depend on a part of the state.

A selector function receives the value returned by useValue and returns the value that will be held by that particular Context.

import React, { useState, useCallback } from "react";
import constate from "constate";

function useCounter() {
  const [count, setCount] = useState(0);
  // increment's reference identity will never change
  const increment = useCallback(() => setCount(prev => prev + 1), []);
  return { count, increment };
}

const [Provider, useCount, useIncrement] = constate(
  useCounter,
  value => value.count, // becomes useCount
  value => value.increment // becomes useIncrement
);

function Button() {
  // since increment never changes, this will never trigger a re-render
  const increment = useIncrement();
  return <button onClick={increment}>+</button>;
}

function Count() {
  const count = useCount();
  return <span>{count}</span>;
}

Contributing

If you find a bug, please create an issue providing instructions to reproduce it. It's always very appreciable if you find the time to fix it. In this case, please submit a PR.

If you're a beginner, it'll be a pleasure to help you contribute. You can start by reading the beginner's guide to contributing to a GitHub project.

When working on this codebase, please use yarn. Run yarn examples to run examples.

License

MIT © Diego Haz

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].