Socket
Socket
Sign inDemoInstall

constate

Package Overview
Dependencies
6
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0-alpha.3 to 1.0.0-alpha.4

dist/ts/src/createUseContextKey.d.ts

15

CHANGELOG.md

@@ -5,2 +5,17 @@ # Change Log

<a name="1.0.0-alpha.4"></a>
# [1.0.0-alpha.4](https://github.com/diegohaz/constate/compare/v1.0.0-alpha.3...v1.0.0-alpha.4) (2018-11-27)
### Features
* Add new `useContextKey` hook ([e0d8cd8](https://github.com/diegohaz/constate/commit/e0d8cd8))
### BREAKING CHANGES
* Removed `unstable_` prefix from `useContextEffect` hooks. They're no longer using React internal stuff, but now they require `useContextKey`. See [docs](https://github.com/diegohaz/constate#usecontexteffect).
<a name="1.0.0-alpha.3"></a>

@@ -7,0 +22,0 @@ # [1.0.0-alpha.3](https://github.com/diegohaz/constate/compare/v1.0.0-alpha.2...v1.0.0-alpha.3) (2018-11-25)

70

dist/constate.cjs.js

@@ -7,6 +7,2 @@ 'use strict';

function getCurrentOwner() {
return React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current;
}
function createUseContextEffect(type) {

@@ -19,17 +15,17 @@ if (type === void 0) {

return function useContextEffect(contextKey, create, inputs) {
var key = contextKey;
var consumer = React.useRef(getCurrentOwner());
var key = contextKey ? contextKey.current : contextKey;
if (consumers[key] == null) {
consumers[key] = consumer.current;
if (key && consumers[key] == null) {
consumers[key] = contextKey;
}
React.useMutationEffect(function () {
if (!key) return undefined;
return function () {
consumers[key] = null;
if (key && consumers[key] === contextKey) {
consumers[key] = null;
}
};
}, [key]);
React[type](function () {
if (!key || consumers[key] === consumer.current) {
if (!key || consumers[key] === contextKey) {
return create();

@@ -47,4 +43,5 @@ }

return function useContextReducer(contextKey, reducer, initialState, initialAction) {
// @ts-ignore
var _React$useContext = React.useContext(contextKey ? context : EmptyContext, contextKey ? hash(contextKey) : undefined),
var key = typeof contextKey === "object" && contextKey ? contextKey.current : contextKey; // @ts-ignore
var _React$useContext = React.useContext(key ? context : EmptyContext, key ? hash(key) : undefined),
contextState = _React$useContext[0],

@@ -57,5 +54,5 @@ setContextState = _React$useContext[1];

if (contextKey) {
if (contextState[contextKey] != null) {
state = contextState[contextKey];
if (key) {
if (contextState[key] != null) {
state = contextState[key];
}

@@ -67,3 +64,3 @@

return Object.assign({}, prevState, (_Object$assign = {}, _Object$assign[contextKey] = reducer(prevState[contextKey], action), _Object$assign));
return Object.assign({}, prevState, (_Object$assign = {}, _Object$assign[key] = reducer(prevState[key], action), _Object$assign));
});

@@ -74,8 +71,8 @@ };

React.useMutationEffect(function () {
if (contextKey && contextState[contextKey] == null && state != null) {
if (key && contextState[key] == null && state != null) {
setContextState(function (prevState) {
if (prevState[contextKey] == null) {
if (prevState[key] == null) {
var _Object$assign2;
return Object.assign({}, prevState, (_Object$assign2 = {}, _Object$assign2[contextKey] = state, _Object$assign2));
return Object.assign({}, prevState, (_Object$assign2 = {}, _Object$assign2[key] = state, _Object$assign2));
}

@@ -86,3 +83,3 @@

}
}, [contextKey]);
}, [key]);
return [state, dispatch];

@@ -107,4 +104,3 @@ };

var _ref = _temp === void 0 ? {} : _temp,
_ref$enabled = _ref.enabled,
enabled = _ref$enabled === void 0 ? true : _ref$enabled;
enabled = _ref.enabled;

@@ -155,2 +151,9 @@ var devtools = React.useRef(null);

function createUseContextKey() {
return function useContextKey(initialContextKey) {
var key = React.useRef(initialContextKey);
return initialContextKey ? key : undefined;
};
}
function createHash(skipLength) {

@@ -218,7 +221,8 @@ var hashMap = {};

Provider: createProvider(Context, initialState),
useContextKey: createUseContextKey(),
useContextState: createUseContextState(Context, hash),
useContextReducer: createUseContextReducer(Context, hash),
unstable_useContextEffect: createUseContextEffect(),
unstable_useContextLayoutEffect: createUseContextEffect("useLayoutEffect"),
unstable_useContextMutationEffect: createUseContextEffect("useMutationEffect")
useContextEffect: createUseContextEffect(),
useContextLayoutEffect: createUseContextEffect("useLayoutEffect"),
useContextMutationEffect: createUseContextEffect("useMutationEffect")
};

@@ -232,5 +236,6 @@ }

useContextState = _createContext.useContextState,
unstable_useContextEffect = _createContext.unstable_useContextEffect,
unstable_useContextLayoutEffect = _createContext.unstable_useContextLayoutEffect,
unstable_useContextMutationEffect = _createContext.unstable_useContextMutationEffect;
useContextKey = _createContext.useContextKey,
useContextEffect = _createContext.useContextEffect,
useContextLayoutEffect = _createContext.useContextLayoutEffect,
useContextMutationEffect = _createContext.useContextMutationEffect;

@@ -242,4 +247,5 @@ exports.createContext = createContext;

exports.useContextState = useContextState;
exports.unstable_useContextEffect = unstable_useContextEffect;
exports.unstable_useContextLayoutEffect = unstable_useContextLayoutEffect;
exports.unstable_useContextMutationEffect = unstable_useContextMutationEffect;
exports.useContextKey = useContextKey;
exports.useContextEffect = useContextEffect;
exports.useContextLayoutEffect = useContextLayoutEffect;
exports.useContextMutationEffect = useContextMutationEffect;
import * as React from 'react';
import { useState, useMemo, createElement, createContext, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, useRef, useMutationEffect, useContext, useReducer, useEffect } from 'react';
import { useState, useMemo, createElement, createContext, useMutationEffect, useContext, useReducer, useRef, useEffect } from 'react';
function getCurrentOwner() {
return __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current;
}
function createUseContextEffect(type) {

@@ -15,17 +11,17 @@ if (type === void 0) {

return function useContextEffect(contextKey, create, inputs) {
var key = contextKey;
var consumer = useRef(getCurrentOwner());
var key = contextKey ? contextKey.current : contextKey;
if (consumers[key] == null) {
consumers[key] = consumer.current;
if (key && consumers[key] == null) {
consumers[key] = contextKey;
}
useMutationEffect(function () {
if (!key) return undefined;
return function () {
consumers[key] = null;
if (key && consumers[key] === contextKey) {
consumers[key] = null;
}
};
}, [key]);
React[type](function () {
if (!key || consumers[key] === consumer.current) {
if (!key || consumers[key] === contextKey) {
return create();

@@ -43,4 +39,5 @@ }

return function useContextReducer(contextKey, reducer, initialState, initialAction) {
// @ts-ignore
var _React$useContext = useContext(contextKey ? context : EmptyContext, contextKey ? hash(contextKey) : undefined),
var key = typeof contextKey === "object" && contextKey ? contextKey.current : contextKey; // @ts-ignore
var _React$useContext = useContext(key ? context : EmptyContext, key ? hash(key) : undefined),
contextState = _React$useContext[0],

@@ -53,5 +50,5 @@ setContextState = _React$useContext[1];

if (contextKey) {
if (contextState[contextKey] != null) {
state = contextState[contextKey];
if (key) {
if (contextState[key] != null) {
state = contextState[key];
}

@@ -63,3 +60,3 @@

return Object.assign({}, prevState, (_Object$assign = {}, _Object$assign[contextKey] = reducer(prevState[contextKey], action), _Object$assign));
return Object.assign({}, prevState, (_Object$assign = {}, _Object$assign[key] = reducer(prevState[key], action), _Object$assign));
});

@@ -70,8 +67,8 @@ };

useMutationEffect(function () {
if (contextKey && contextState[contextKey] == null && state != null) {
if (key && contextState[key] == null && state != null) {
setContextState(function (prevState) {
if (prevState[contextKey] == null) {
if (prevState[key] == null) {
var _Object$assign2;
return Object.assign({}, prevState, (_Object$assign2 = {}, _Object$assign2[contextKey] = state, _Object$assign2));
return Object.assign({}, prevState, (_Object$assign2 = {}, _Object$assign2[key] = state, _Object$assign2));
}

@@ -82,3 +79,3 @@

}
}, [contextKey]);
}, [key]);
return [state, dispatch];

@@ -103,4 +100,3 @@ };

var _ref = _temp === void 0 ? {} : _temp,
_ref$enabled = _ref.enabled,
enabled = _ref$enabled === void 0 ? true : _ref$enabled;
enabled = _ref.enabled;

@@ -151,2 +147,9 @@ var devtools = useRef(null);

function createUseContextKey() {
return function useContextKey(initialContextKey) {
var key = useRef(initialContextKey);
return initialContextKey ? key : undefined;
};
}
function createHash(skipLength) {

@@ -214,7 +217,8 @@ var hashMap = {};

Provider: createProvider(Context, initialState),
useContextKey: createUseContextKey(),
useContextState: createUseContextState(Context, hash),
useContextReducer: createUseContextReducer(Context, hash),
unstable_useContextEffect: createUseContextEffect(),
unstable_useContextLayoutEffect: createUseContextEffect("useLayoutEffect"),
unstable_useContextMutationEffect: createUseContextEffect("useMutationEffect")
useContextEffect: createUseContextEffect(),
useContextLayoutEffect: createUseContextEffect("useLayoutEffect"),
useContextMutationEffect: createUseContextEffect("useMutationEffect")
};

@@ -228,6 +232,7 @@ }

useContextState = _createContext.useContextState,
unstable_useContextEffect = _createContext.unstable_useContextEffect,
unstable_useContextLayoutEffect = _createContext.unstable_useContextLayoutEffect,
unstable_useContextMutationEffect = _createContext.unstable_useContextMutationEffect;
useContextKey = _createContext.useContextKey,
useContextEffect = _createContext.useContextEffect,
useContextLayoutEffect = _createContext.useContextLayoutEffect,
useContextMutationEffect = _createContext.useContextMutationEffect;
export { createContext$1 as createContext, Context, Provider, useContextReducer, useContextState, unstable_useContextEffect, unstable_useContextLayoutEffect, unstable_useContextMutationEffect };
export { createContext$1 as createContext, Context, Provider, useContextReducer, useContextState, useContextKey, useContextEffect, useContextLayoutEffect, useContextMutationEffect };

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t(e.constate={},e.React)}(this,function(e,E){"use strict";function l(o){void 0===o&&(o="useEffect");var c={};return function(e,t,n){var u=e,r=E.useRef(E.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current);null==c[u]&&(c[u]=r.current),E.useMutationEffect(function(){if(u)return function(){c[u]=null}},[u]),E[o](function(){if(!u||c[u]===r.current)return t()},n?[u].concat(n):void 0)}}var d=E.createContext([]);function v(a,l){return function(u,r,e,t){var n=E.useContext(u?a:d,u?l(u):void 0),o=n[0],c=n[1],f=E.useReducer(r,e,t),i=f[0],s=f[1];return u&&(null!=o[u]&&(i=o[u]),s=function(n){return c(function(e){var t;return Object.assign({},e,((t={})[u]=r(e[u],n),t))})}),E.useMutationEffect(function(){u&&null==o[u]&&null!=i&&c(function(e){return null!=e[u]?e:Object.assign({},e,((t={})[u]=i,t));var t})},[u]),[i,s]}}function _(e,t){return"function"==typeof t?t(e):t}var x="undefined"!=typeof window&&window.__REDUX_DEVTOOLS_EXTENSION__;function C(v,_){return function(e){var n,t,u,r,o,c,f,i,s=e.children,a=e.devtools,l=E.useState(_),d=E.useMemo(function(){return l},[l[0]]);return n=l[0],t=l[1],r=(void 0===(u={enabled:a})?{}:u).enabled,o=void 0===r||r,c=E.useRef(null),f=E.useRef(null),i=E.useRef(null),E.useEffect(function(){if(o&&x)return c.current=x.connect(),c.current.init(n),c.current.subscribe(function(e){"DISPATCH"===e.type&&e.state&&(i.current=JSON.parse(e.state),t(i.current))}),function(){c.current&&(c.current.unsubscribe(),x.disconnect())}},[o]),E.useEffect(function(){if(o&&x){if(i.current!==n){var e;for(var t in n)f.current&&n[t]!==f.current[t]&&(e=t);e&&c.current&&c.current.send(e,n)}f.current=n}},[n,o]),E.createElement(v.Provider,{value:d},s)}}function t(e,t){var n,u,r,o,c,f,i=(n=1,u={},function(e){if(void 0!==u[e])return u[e];var t=Object.keys(u).length;return u[e]=1<<t%(30-n)+n,u[e]}),s=void 0===t?(r=i,function(e,t){var n=1;if("object"!=typeof t||Array.isArray(t)||null===t)return n;for(var u in t)e[u]!==t[u]&&(n|=r(u));return n}):t,a=E.createContext([e,function(){}],s?function(e,t){var n=e[0],u=t[0];return s(n,u)}:void 0);return{Context:a,Provider:C(a,e),useContextState:(o=a,c=i,f=v(o,c),function(e,t){return f(e,_,t)}),useContextReducer:v(a,i),unstable_useContextEffect:l(),unstable_useContextLayoutEffect:l("useLayoutEffect"),unstable_useContextMutationEffect:l("useMutationEffect")}}var n=t({}),u=n.Context,r=n.Provider,o=n.useContextReducer,c=n.useContextState,f=n.unstable_useContextEffect,i=n.unstable_useContextLayoutEffect,s=n.unstable_useContextMutationEffect;e.createContext=t,e.Context=u,e.Provider=r,e.useContextReducer=o,e.useContextState=c,e.unstable_useContextEffect=f,e.unstable_useContextLayoutEffect=i,e.unstable_useContextMutationEffect=s,Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t(e.constate={},e.React)}(this,function(e,x){"use strict";function d(r){void 0===r&&(r="useEffect");var o={};return function(e,t,n){var u=e?e.current:e;u&&null==o[u]&&(o[u]=e),x.useMutationEffect(function(){return function(){u&&o[u]===e&&(o[u]=null)}},[u]),x[r](function(){if(!u||o[u]===e)return t()},n?[u].concat(n):void 0)}}var l=x.createContext([]);function v(d,v){return function(e,u,t,n){var r="object"==typeof e&&e?e.current:e,o=x.useContext(r?d:l,r?v(r):void 0),c=o[0],f=o[1],i=x.useReducer(u,t,n),s=i[0],a=i[1];return r&&(null!=c[r]&&(s=c[r]),a=function(n){return f(function(e){var t;return Object.assign({},e,((t={})[r]=u(e[r],n),t))})}),x.useMutationEffect(function(){r&&null==c[r]&&null!=s&&f(function(e){return null!=e[r]?e:Object.assign({},e,((t={})[r]=s,t));var t})},[r]),[s,a]}}function C(e,t){return"function"==typeof t?t(e):t}var E="undefined"!=typeof window&&window.__REDUX_DEVTOOLS_EXTENSION__;function y(v,l){return function(e){var n,t,u,r,o,c,f,i=e.children,s=e.devtools,a=x.useState(l),d=x.useMemo(function(){return a},[a[0]]);return n=a[0],t=a[1],r=(void 0===(u={enabled:s})?{}:u).enabled,o=x.useRef(null),c=x.useRef(null),f=x.useRef(null),x.useEffect(function(){if(r&&E)return o.current=E.connect(),o.current.init(n),o.current.subscribe(function(e){"DISPATCH"===e.type&&e.state&&(f.current=JSON.parse(e.state),t(f.current))}),function(){o.current&&(o.current.unsubscribe(),E.disconnect())}},[r]),x.useEffect(function(){if(r&&E){if(f.current!==n){var e;for(var t in n)c.current&&n[t]!==c.current[t]&&(e=t);e&&o.current&&o.current.send(e,n)}c.current=n}},[n,r]),x.createElement(v.Provider,{value:d},i)}}function t(e,t){var n,u,r,o,c,f,i=(n=1,u={},function(e){if(void 0!==u[e])return u[e];var t=Object.keys(u).length;return u[e]=1<<t%(30-n)+n,u[e]}),s=void 0===t?(r=i,function(e,t){var n=1;if("object"!=typeof t||Array.isArray(t)||null===t)return n;for(var u in t)e[u]!==t[u]&&(n|=r(u));return n}):t,a=x.createContext([e,function(){}],s?function(e,t){var n=e[0],u=t[0];return s(n,u)}:void 0);return{Context:a,Provider:y(a,e),useContextKey:function(e){var t=x.useRef(e);return e?t:void 0},useContextState:(o=a,c=i,f=v(o,c),function(e,t){return f(e,C,t)}),useContextReducer:v(a,i),useContextEffect:d(),useContextLayoutEffect:d("useLayoutEffect"),useContextMutationEffect:d("useMutationEffect")}}var n=t({}),u=n.Context,r=n.Provider,o=n.useContextReducer,c=n.useContextState,f=n.useContextKey,i=n.useContextEffect,s=n.useContextLayoutEffect,a=n.useContextMutationEffect;e.createContext=t,e.Context=u,e.Provider=r,e.useContextReducer=o,e.useContextState=c,e.useContextKey=f,e.useContextEffect=i,e.useContextLayoutEffect=s,e.useContextMutationEffect=a,Object.defineProperty(e,"__esModule",{value:!0})});

@@ -9,8 +9,9 @@ import * as React from "react";

Provider: ({ children, devtools }: ProviderProps) => JSX.Element;
useContextKey: import("./createUseContextKey").UseContextKey<State>;
useContextState: import("./createUseContextState").UseContextState<State>;
useContextReducer: import("./createUseContextReducer").UseContextReducer<State>;
unstable_useContextEffect: (contextKey: keyof State | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
unstable_useContextLayoutEffect: (contextKey: keyof State | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
unstable_useContextMutationEffect: (contextKey: keyof State | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
useContextEffect: (contextKey: React.MutableRefObject<keyof State> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
useContextLayoutEffect: (contextKey: React.MutableRefObject<keyof State> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
useContextMutationEffect: (contextKey: React.MutableRefObject<keyof State> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
};
export default createContext;

@@ -1,2 +0,3 @@

declare function createUseContextEffect<State>(type?: "useEffect" | "useMutationEffect" | "useLayoutEffect"): (contextKey: keyof State | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
import * as React from "react";
declare function createUseContextEffect<State>(type?: "useEffect" | "useMutationEffect" | "useLayoutEffect"): (contextKey: React.MutableRefObject<keyof State> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
export default createUseContextEffect;
import * as React from "react";
import { ContextReducer, ContextState, Reducer } from "./types";
export interface UseContextReducer<State> {
<K extends keyof State, Action>(contextKey: K | undefined | null, reducer: Reducer<State[K], Action>, initialState?: null, initialAction?: Action): ContextReducer<State[K], Action>;
<K extends keyof State, S extends State[K], Action>(contextKey: K | undefined | null, reducer: Reducer<S, Action>, initialState?: S | (() => S) | null, initialAction?: Action): ContextReducer<S, Action>;
<K extends keyof State, Action>(contextKey: React.MutableRefObject<K> | K | undefined | null, reducer: Reducer<State[K], Action>, initialState?: null, initialAction?: Action): ContextReducer<State[K], Action>;
<K extends keyof State, S extends State[K], Action>(contextKey: React.MutableRefObject<K> | K | undefined | null, reducer: Reducer<S, Action>, initialState?: S | (() => S) | null, initialAction?: Action): ContextReducer<S, Action>;
}
declare function createUseContextReducer<State>(context: React.Context<ContextState<State>>, hash: (key: string) => number): UseContextReducer<State>;
export default createUseContextReducer;
import * as React from "react";
import { ContextState } from "./types";
export interface UseContextState<State> {
<K extends keyof State>(contextKey?: K | null): ContextState<State[K]>;
<K extends keyof State, S extends State[K]>(contextKey?: K | null, initialState?: S | (() => S) | null): ContextState<S>;
<K extends keyof State>(contextKey?: React.MutableRefObject<K> | K | null): ContextState<State[K]>;
<K extends keyof State, S extends State[K]>(contextKey?: React.MutableRefObject<K> | K | null, initialState?: S | (() => S) | null): ContextState<S>;
}
declare function createUseContextState<State>(context: React.Context<ContextState<State>>, hash: (key: string) => number): UseContextState<State>;
export default createUseContextState;

@@ -11,3 +11,5 @@ /// <reference types="react" />

[key: string]: any;
}>, unstable_useContextEffect: (contextKey: string | number | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void, unstable_useContextLayoutEffect: (contextKey: string | number | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void, unstable_useContextMutationEffect: (contextKey: string | number | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
export { createContext, Context, Provider, useContextReducer, useContextState, unstable_useContextEffect, unstable_useContextLayoutEffect, unstable_useContextMutationEffect };
}>, useContextKey: import("./createUseContextKey").UseContextKey<{
[key: string]: any;
}>, useContextEffect: (contextKey: import("react").MutableRefObject<string | number> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void, useContextLayoutEffect: (contextKey: import("react").MutableRefObject<string | number> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void, useContextMutationEffect: (contextKey: import("react").MutableRefObject<string | number> | null | undefined, create: () => void | (() => void), inputs?: ReadonlyArray<any> | undefined) => void;
export { createContext, Context, Provider, useContextReducer, useContextState, useContextKey, useContextEffect, useContextLayoutEffect, useContextMutationEffect };
{
"name": "constate",
"version": "1.0.0-alpha.3",
"version": "1.0.0-alpha.4",
"description": "Yet another React state management library that lets you work with local state and scale up to global state with ease",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -6,24 +6,30 @@ <p align="center">

<p align="center">
1 kB React state management library that lets you write contextual state<br>
as if it were local state, using <a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a>.
</p>
# Constate
<br>
<a href="https://npmjs.org/package/constate"><img alt="NPM version" src="https://img.shields.io/npm/v/constate/next.svg?style=flat-square"></a>
<a href="https://npmjs.org/package/constate"><img alt="NPM downloads" src="https://img.shields.io/npm/dm/constate.svg?style=flat-square"></a>
<a href="https://unpkg.com/constate@next"><img alt="Gzip size" src="https://img.badgesize.io/https://unpkg.com/constate@next?style=flat-square&compression=gzip"></a>
<a href="https://david-dm.org/diegohaz/constate"><img alt="Dependencies" src="https://img.shields.io/david/diegohaz/constate/master.svg?style=flat-square"></a>
<a href="https://travis-ci.org/diegohaz/constate"><img alt="Build Status" src="https://img.shields.io/travis/diegohaz/constate/master.svg?style=flat-square"></a>
<a href="https://codecov.io/gh/diegohaz/constate/branch/master"><img alt="Coverage Status" src="https://img.shields.io/codecov/c/github/diegohaz/constate/master.svg?style=flat-square"></a>
<p align="center">
<a href="https://npmjs.org/package/constate"><img alt="NPM version" src="https://img.shields.io/npm/v/constate/next.svg?style=flat-square"></a>
<a href="https://unpkg.com/constate@next"><img alt="Gzip size" src="https://img.badgesize.io/https://unpkg.com/constate@next?style=flat-square&compression=gzip"></a>
<a href="https://david-dm.org/diegohaz/constate"><img alt="Dependencies" src="https://img.shields.io/david/diegohaz/constate/master.svg?style=flat-square"></a>
<a href="https://travis-ci.org/diegohaz/constate"><img alt="Build Status" src="https://img.shields.io/travis/diegohaz/constate/master.svg?style=flat-square"></a>
<a href="https://codecov.io/gh/diegohaz/constate/branch/master"><img alt="Coverage Status" src="https://img.shields.io/codecov/c/github/diegohaz/constate/master.svg?style=flat-square"></a>
</p>
~1 kB React state management library that lets you write contextual state as if it were local state using [React Hooks](https://reactjs.org/docs/hooks-intro.html) and [React Context](https://reactjs.org/docs/context.html).
<br>
<p align="center">
<strong>🎮 Play with CodeSandbox examples</strong>
<br>
<a href="https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/counter">Counter</a>
</p>
<table>
<thead>
<tr>
<th colspan="3">🕹 CodeSandbox demos 🕹</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/counter?module=/App.js">Counter</a></td>
<td><a href="https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/theming?module=/App.js">Theming</a></td>
<td><a href="https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/i18n?module=/App.js">I18n</a></td>
</tr>
</tbody>
</table>

@@ -36,16 +42,18 @@ <br>

function useCounter(context) {
// replacing React.useState(0);
const [count, setCount] = useContextState(context, 0);
// 1. Create a custom hook
function useCounter(key) {
// 2. Replace React.useState(0) by useContextState(key, 0)
const [count, setCount] = useContextState(key, 0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return { count, increment, decrement };
return { count, increment };
}
function DecrementButton() {
const { decrement } = useCounter("counter1");
return <button onClick={decrement}>-</button>;
function Count() {
// 3. Consume the custom hook as usual
const { count } = useCounter("counter1");
return <span>{count}</span>
}
function IncrementButton() {
// 4. Consume the same key in other components
const { increment } = useCounter("counter1");

@@ -55,11 +63,6 @@ return <button onClick={increment}>+</button>;

function Count() {
const { count } = useCounter("counter1");
return <span>{count}</span>
}
function App() {
// 5. Wrap your app with Provider
return (
<Provider>
<DecrementButton />
<Count />

@@ -80,2 +83,4 @@ <IncrementButton />

- [`useContextReducer`](#usecontextreducer)
- [`useContextKey`](#usecontextkey)
- [`useContextEffect`](#usecontexteffect)
- [`createContext`](#createcontext)

@@ -126,4 +131,6 @@

`useContextState` has the same API as [`React.useState`](https://reactjs.org/docs/hooks-reference.html#usestate), except that it receives `contextKey` as the first argument.
`useContextState` has the same API as [`React.useState`](https://reactjs.org/docs/hooks-reference.html#usestate), except that it receives `contextKey` as the first argument. It can be either a string or the return value of [`useContextKey`](#usecontextkey).
All `useContextState` calls with the same `contextKey` throughout components in the [`Provider`](#provider) tree will share the same state.
```jsx

@@ -157,4 +164,4 @@ import { useContextState } from "constate";

function useCounter(context) {
const [count, setCount] = useContextState(context, 0);
function useCounter(key) {
const [count, setCount] = useContextState(key, 0);
const increment = () => setCount(count + 1);

@@ -181,3 +188,3 @@ return { count, increment };

Just like [`useContextState`](#usecontextstate), `useContextReducer` works similarly to [`React.useReducer`](https://reactjs.org/docs/hooks-reference.html#usereducer), but accepting a `contextKey` argument:
Just like [`useContextState`](#usecontextstate), `useContextReducer` works similarly to [`React.useReducer`](https://reactjs.org/docs/hooks-reference.html#usereducer), but accepting a `contextKey` argument, which can be either a string or the return value of [`useContextKey`](#usecontextkey):

@@ -195,4 +202,4 @@ ```jsx

function useCounter(context) {
const [count, dispatch] = useContextReducer(context, reducer, 0);
function useCounter(key) {
const [count, dispatch] = useContextReducer(key, reducer, 0);
const increment = () => dispatch({ type: "INCREMENT" });

@@ -211,2 +218,69 @@ const decrement = () => dispatch({ type: "DECREMENT" });

## `useContextKey`
<sup><a href="#table-of-contents">↑ Back to top</a></sup>
Instead of passing strings to [`useContextState`](#usecontextstate) and [`useContextReducer`](#usecontextreducer), you can create a reference to the context key.
```js
import { useContextKey } from "constate";
function Counter() {
const key = useContextKey("counter1");
const [count, setCount] = useContextState(key, 0);
...
}
```
It uses [`React.useRef`](https://reactjs.org/docs/hooks-reference.html#useref) underneath and is required when using [`useContextEffect`](#usecontexteffect).
<br>
## `useContextEffect`
<sup><a href="#table-of-contents">↑ Back to top</a></sup>
Constate provides all contextual versions of [`React.useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect), such as `useContextEffect`, `useContextMutationEffect` and `useContextLayoutEffect`.
They receive `contextKey` as the first argument. Unless [`useContextState`](#usecontextstate) and [`useContextReducer`](#usecontextreducer), it's limited to the value returned by [`useContextKey`](#usecontextkey). If `contextKey` is `null` or `undefined`, the hook will work exactly as the React one.
```js
import { Provider, useContextKey, useContextEffect } from "constate";
let count = 0;
function useCounter(context) {
// useContextKey is required for effects
const key = useContextKey(context);
useContextEffect(key, () => {
count += 1;
}, []);
}
function ContextualCounter1() {
useCounter("counter1");
...
}
function ContextualCounter2() {
useCounter("counter1");
...
}
function App() {
return (
<Provider>
<ContextualCounter1 />
<ContextualCounter2 />
</Provider>
);
}
```
In the example above, if we were using [`React.useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect), `count` would be `2`. With `useContextEffect`, it's `1`.
`useContextEffect` ensures that the function will be called only once per `contextKey` no matter how many components are using it.
<br>
## `createContext`

@@ -222,3 +296,11 @@

const { Provider, useContextState, useContextReducer } = createContext({
const {
Provider,
useContextKey,
useContextState,
useContextReducer,
useContextEffect,
useContextLayoutEffect,
useContextMutationEffect
} = createContext({
counter1: 0,

@@ -230,3 +312,11 @@ posts: [

export { Provider, useContextState, useContextReducer };
export {
Provider,
useContextKey,
useContextState,
useContextReducer,
useContextEffect,
useContextLayoutEffect,
useContextMutationEffect
};
```

@@ -233,0 +323,0 @@

import * as React from "react";
// I'm unemployed anyway
function getCurrentOwner() {
return (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.ReactCurrentOwner.current;
}
function createUseContextEffect<State>(
type: "useEffect" | "useMutationEffect" | "useLayoutEffect" = "useEffect"
) {
const consumers: { [key: string]: React.MutableRefObject<any> | null } = {};
const consumers: {
[K in keyof State]?: React.MutableRefObject<K> | null
} = {};
return function useContextEffect(
contextKey: keyof State | undefined | null,
contextKey: React.MutableRefObject<keyof State> | null | undefined,
create: () => void | (() => void),
inputs?: ReadonlyArray<any>
) {
const key = contextKey as string;
const consumer = React.useRef(getCurrentOwner());
if (consumers[key] == null) {
consumers[key] = consumer.current;
const key = contextKey ? contextKey.current : contextKey;
if (key && consumers[key] == null) {
consumers[key] = contextKey!;
}
React.useMutationEffect(
() => {
if (!key) return undefined;
return () => {
() => () => {
if (key && consumers[key] === contextKey) {
consumers[key] = null;
};
}
},

@@ -37,3 +32,3 @@ [key]

() => {
if (!key || consumers[key] === consumer.current) {
if (!key || consumers[key] === contextKey) {
return create();

@@ -40,0 +35,0 @@ }

@@ -6,3 +6,3 @@ import * as React from "react";

<K extends keyof State, Action>(
contextKey: K | undefined | null,
contextKey: React.MutableRefObject<K> | K | undefined | null,
reducer: Reducer<State[K], Action>,

@@ -14,3 +14,3 @@ initialState?: null,

<K extends keyof State, S extends State[K], Action>(
contextKey: K | undefined | null,
contextKey: React.MutableRefObject<K> | K | undefined | null,
reducer: Reducer<S, Action>,

@@ -29,3 +29,7 @@ initialState?: S | (() => S) | null,

return function useContextReducer(
contextKey: keyof State | undefined | null,
contextKey:
| React.MutableRefObject<keyof State>
| keyof State
| undefined
| null,
reducer: Reducer<State[keyof State], any>,

@@ -35,6 +39,11 @@ initialState?: State[keyof State],

) {
const key =
typeof contextKey === "object" && contextKey
? contextKey.current
: contextKey;
// @ts-ignore
const [contextState, setContextState] = React.useContext(
contextKey ? context : EmptyContext,
contextKey ? hash(contextKey as string) : undefined
key ? context : EmptyContext,
key ? hash(key as string) : undefined
);

@@ -48,5 +57,5 @@

if (contextKey) {
if (contextState[contextKey] != null) {
state = contextState[contextKey];
if (key) {
if (contextState[key] != null) {
state = contextState[key];
}

@@ -57,3 +66,3 @@

Object.assign({}, prevState, {
[contextKey]: reducer(prevState[contextKey], action)
[key]: reducer(prevState[key], action)
})

@@ -65,7 +74,7 @@ );

() => {
if (contextKey && contextState[contextKey] == null && state != null) {
if (key && contextState[key] == null && state != null) {
setContextState((prevState: State) => {
if (prevState[contextKey] == null) {
if (prevState[key] == null) {
return Object.assign({}, prevState, {
[contextKey]: state
[key]: state
});

@@ -77,3 +86,3 @@ }

},
[contextKey]
[key]
);

@@ -80,0 +89,0 @@

@@ -6,6 +6,8 @@ import * as React from "react";

export interface UseContextState<State> {
<K extends keyof State>(contextKey?: K | null): ContextState<State[K]>;
<K extends keyof State>(
contextKey?: React.MutableRefObject<K> | K | null
): ContextState<State[K]>;
<K extends keyof State, S extends State[K]>(
contextKey?: K | null,
contextKey?: React.MutableRefObject<K> | K | null,
initialState?: S | (() => S) | null

@@ -12,0 +14,0 @@ ): ContextState<S>;

@@ -8,5 +8,6 @@ import createContext from "./createContext";

useContextState,
unstable_useContextEffect,
unstable_useContextLayoutEffect,
unstable_useContextMutationEffect
useContextKey,
useContextEffect,
useContextLayoutEffect,
useContextMutationEffect
} = createContext<{ [key: string]: any }>({});

@@ -20,5 +21,6 @@

useContextState,
unstable_useContextEffect,
unstable_useContextLayoutEffect,
unstable_useContextMutationEffect
useContextKey,
useContextEffect,
useContextLayoutEffect,
useContextMutationEffect
};

@@ -10,3 +10,3 @@ import * as React from "react";

setState: SetState<State>,
{ enabled = true }: { enabled?: boolean } = {}
{ enabled }: { enabled?: boolean } = {}
) {

@@ -13,0 +13,0 @@ const devtools = React.useRef<ReturnType<

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc