New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mobx-react-lite

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mobx-react-lite - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0-alpha.0

dist/reactionCleanupTracking.d.ts

175

dist/custom.js

@@ -112,2 +112,13 @@ (function (global, factory) {

function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {

@@ -131,12 +142,80 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

function printDebugValue(v) {
if (!v.current) {
return "<unknown>";
return mobx.getDependencyTree(v);
}
function createTrackingData(reaction) {
var trackingData = {
cleanAt: Date.now() + CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS,
reaction: reaction
};
return trackingData;
}
/**
* The minimum time before we'll clean up a Reaction created in a render
* for a component that hasn't managed to run its effects. This needs to
* be big enough to ensure that a component won't turn up and have its
* effects run without being re-rendered.
*/
var CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS = 10000;
/**
* The frequency with which we'll check for leaked reactions.
*/
var CLEANUP_TIMER_LOOP_MILLIS = 10000;
/**
* Reactions created by components that have yet to be fully mounted.
*/
var uncommittedReactionRefs = new Set();
/**
* Latest 'uncommitted reactions' cleanup timer handle.
*/
var reactionCleanupHandle;
function ensureCleanupTimerRunning() {
if (reactionCleanupHandle === undefined) {
reactionCleanupHandle = setTimeout(cleanUncommittedReactions, CLEANUP_TIMER_LOOP_MILLIS);
}
return mobx.getDependencyTree(v.current);
}
function scheduleCleanupOfReactionIfLeaked(ref) {
uncommittedReactionRefs.add(ref);
ensureCleanupTimerRunning();
}
function recordReactionAsCommitted(reactionRef) {
uncommittedReactionRefs.delete(reactionRef);
}
/**
* Run by the cleanup timer to dispose any outstanding reactions
*/
function cleanUncommittedReactions() {
var e_1, _a;
reactionCleanupHandle = undefined;
// Loop through all the candidate leaked reactions; those older
// than CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS get tidied.
var now = Date.now();
try {
for (var uncommittedReactionRefs_1 = __values(uncommittedReactionRefs), uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next(); !uncommittedReactionRefs_1_1.done; uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next()) {
var ref = uncommittedReactionRefs_1_1.value;
var tracking = ref.current;
if (tracking) {
if (now >= tracking.cleanAt) {
// It's time to tidy up this leaked reaction.
tracking.reaction.dispose();
ref.current = null;
uncommittedReactionRefs.delete(ref);
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uncommittedReactionRefs_1_1 && !uncommittedReactionRefs_1_1.done && (_a = uncommittedReactionRefs_1.return)) _a.call(uncommittedReactionRefs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (uncommittedReactionRefs.size > 0) {
// We've just finished a round of cleanups but there are still
// some leak candidates outstanding.
ensureCleanupTimerRunning();
}
}
var EMPTY_ARRAY = [];
function useUnmount(fn) {
react.useEffect(function () { return fn; }, EMPTY_ARRAY);
}
function useForceUpdate() {

@@ -151,2 +230,5 @@ var _a = __read(react.useState(0), 2), setTick = _a[1];

var EMPTY_OBJECT = {};
function observerComponentNameFor(baseComponentName) {
return "observer" + baseComponentName;
}
function useObserver(fn, baseComponentName, options) {

@@ -160,12 +242,60 @@ if (baseComponentName === void 0) { baseComponentName = "observed"; }

var forceUpdate = wantedForceUpdateHook();
var reaction = react.useRef(null);
if (!reaction.current) {
reaction.current = new mobx.Reaction("observer(" + baseComponentName + ")", function () {
forceUpdate();
// StrictMode/ConcurrentMode/Suspense may mean that our component is
// rendered and abandoned multiple times, so we need to track leaked
// Reactions.
var reactionTrackingRef = react.useRef(null);
if (!reactionTrackingRef.current) {
// First render for this component (or first time since a previous
// reaction from an abandoned render was disposed).
var newReaction_1 = new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// Observable has changed, meaning we want to re-render
// BUT if we're a component that hasn't yet got to the useEffect()
// stage, we might be a component that _started_ to render, but
// got dropped, and we don't want to make state changes then.
// (It triggers warnings in StrictMode, for a start.)
if (trackingData_1.mounted) {
// We have reached useEffect(), so we're mounted, and can trigger an update
forceUpdate();
}
else {
// We haven't yet reached useEffect(), so we'll need to trigger a re-render
// when (and if) useEffect() arrives. The easiest way to do that is just to
// drop our current reaction and allow useEffect() to recreate it.
newReaction_1.dispose();
reactionTrackingRef.current = null;
}
});
var trackingData_1 = createTrackingData(newReaction_1);
reactionTrackingRef.current = trackingData_1;
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef);
}
var reaction = reactionTrackingRef.current.reaction;
react.useDebugValue(reaction, printDebugValue);
useUnmount(function () {
reaction.current.dispose();
});
react.useEffect(function () {
// Called on first mount only
recordReactionAsCommitted(reactionTrackingRef);
if (reactionTrackingRef.current) {
// Great. We've already got our reaction from our render;
// all we need to do is to record that it's now mounted,
// to allow future observable changes to trigger re-renders
reactionTrackingRef.current.mounted = true;
}
else {
// The reaction we set up in our render has been disposed.
// This is either due to bad timings of renderings, e.g. our
// component was paused for a _very_ long time, and our
// reaction got cleaned up, or we got a observable change
// between render and useEffect
// Re-create the reaction
reactionTrackingRef.current = {
reaction: new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// We've definitely already been mounted at this point
forceUpdate();
}),
cleanAt: Infinity
};
forceUpdate();
}
return function () { return reactionTrackingRef.current.reaction.dispose(); };
}, []);
// render the original component, but have the

@@ -176,3 +306,3 @@ // reaction track the observables, so that rendering

var exception;
reaction.current.track(function () {
reaction.track(function () {
try {

@@ -186,3 +316,2 @@ rendering = fn();

if (exception) {
reaction.current.dispose();
throw exception; // re-throw any exceptions catched during rendering

@@ -195,3 +324,3 @@ }

function observer(baseComponent, options) {
// The working of observer is explaind step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
// The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
if (isUsingStaticRendering()) {

@@ -272,11 +401,11 @@ return baseComponent;

exports.useObservable = useObservable;
exports.Observer = ObserverComponent;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.observer = observer;
exports.useComputed = useComputed;
exports.useDisposable = useDisposable;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.useForceUpdate = useForceUpdate;
exports.useObservable = useObservable;
exports.useObserver = useObserver;
exports.useStaticRendering = useStaticRendering;
exports.observer = observer;
exports.useObserver = useObserver;
exports.Observer = ObserverComponent;
exports.useForceUpdate = useForceUpdate;

@@ -283,0 +412,0 @@ Object.defineProperty(exports, '__esModule', { value: true });

@@ -109,2 +109,13 @@ import { spy, observable, computed, getDependencyTree, Reaction } from 'mobx';

function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {

@@ -128,12 +139,80 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

function printDebugValue(v) {
if (!v.current) {
return "<unknown>";
return getDependencyTree(v);
}
function createTrackingData(reaction) {
var trackingData = {
cleanAt: Date.now() + CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS,
reaction: reaction
};
return trackingData;
}
/**
* The minimum time before we'll clean up a Reaction created in a render
* for a component that hasn't managed to run its effects. This needs to
* be big enough to ensure that a component won't turn up and have its
* effects run without being re-rendered.
*/
var CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS = 10000;
/**
* The frequency with which we'll check for leaked reactions.
*/
var CLEANUP_TIMER_LOOP_MILLIS = 10000;
/**
* Reactions created by components that have yet to be fully mounted.
*/
var uncommittedReactionRefs = new Set();
/**
* Latest 'uncommitted reactions' cleanup timer handle.
*/
var reactionCleanupHandle;
function ensureCleanupTimerRunning() {
if (reactionCleanupHandle === undefined) {
reactionCleanupHandle = setTimeout(cleanUncommittedReactions, CLEANUP_TIMER_LOOP_MILLIS);
}
return getDependencyTree(v.current);
}
function scheduleCleanupOfReactionIfLeaked(ref) {
uncommittedReactionRefs.add(ref);
ensureCleanupTimerRunning();
}
function recordReactionAsCommitted(reactionRef) {
uncommittedReactionRefs.delete(reactionRef);
}
/**
* Run by the cleanup timer to dispose any outstanding reactions
*/
function cleanUncommittedReactions() {
var e_1, _a;
reactionCleanupHandle = undefined;
// Loop through all the candidate leaked reactions; those older
// than CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS get tidied.
var now = Date.now();
try {
for (var uncommittedReactionRefs_1 = __values(uncommittedReactionRefs), uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next(); !uncommittedReactionRefs_1_1.done; uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next()) {
var ref = uncommittedReactionRefs_1_1.value;
var tracking = ref.current;
if (tracking) {
if (now >= tracking.cleanAt) {
// It's time to tidy up this leaked reaction.
tracking.reaction.dispose();
ref.current = null;
uncommittedReactionRefs.delete(ref);
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uncommittedReactionRefs_1_1 && !uncommittedReactionRefs_1_1.done && (_a = uncommittedReactionRefs_1.return)) _a.call(uncommittedReactionRefs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (uncommittedReactionRefs.size > 0) {
// We've just finished a round of cleanups but there are still
// some leak candidates outstanding.
ensureCleanupTimerRunning();
}
}
var EMPTY_ARRAY = [];
function useUnmount(fn) {
useEffect(function () { return fn; }, EMPTY_ARRAY);
}
function useForceUpdate() {

@@ -148,2 +227,5 @@ var _a = __read(useState(0), 2), setTick = _a[1];

var EMPTY_OBJECT = {};
function observerComponentNameFor(baseComponentName) {
return "observer" + baseComponentName;
}
function useObserver(fn, baseComponentName, options) {

@@ -157,12 +239,60 @@ if (baseComponentName === void 0) { baseComponentName = "observed"; }

var forceUpdate = wantedForceUpdateHook();
var reaction = useRef(null);
if (!reaction.current) {
reaction.current = new Reaction("observer(" + baseComponentName + ")", function () {
forceUpdate();
// StrictMode/ConcurrentMode/Suspense may mean that our component is
// rendered and abandoned multiple times, so we need to track leaked
// Reactions.
var reactionTrackingRef = useRef(null);
if (!reactionTrackingRef.current) {
// First render for this component (or first time since a previous
// reaction from an abandoned render was disposed).
var newReaction_1 = new Reaction(observerComponentNameFor(baseComponentName), function () {
// Observable has changed, meaning we want to re-render
// BUT if we're a component that hasn't yet got to the useEffect()
// stage, we might be a component that _started_ to render, but
// got dropped, and we don't want to make state changes then.
// (It triggers warnings in StrictMode, for a start.)
if (trackingData_1.mounted) {
// We have reached useEffect(), so we're mounted, and can trigger an update
forceUpdate();
}
else {
// We haven't yet reached useEffect(), so we'll need to trigger a re-render
// when (and if) useEffect() arrives. The easiest way to do that is just to
// drop our current reaction and allow useEffect() to recreate it.
newReaction_1.dispose();
reactionTrackingRef.current = null;
}
});
var trackingData_1 = createTrackingData(newReaction_1);
reactionTrackingRef.current = trackingData_1;
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef);
}
var reaction = reactionTrackingRef.current.reaction;
useDebugValue(reaction, printDebugValue);
useUnmount(function () {
reaction.current.dispose();
});
useEffect(function () {
// Called on first mount only
recordReactionAsCommitted(reactionTrackingRef);
if (reactionTrackingRef.current) {
// Great. We've already got our reaction from our render;
// all we need to do is to record that it's now mounted,
// to allow future observable changes to trigger re-renders
reactionTrackingRef.current.mounted = true;
}
else {
// The reaction we set up in our render has been disposed.
// This is either due to bad timings of renderings, e.g. our
// component was paused for a _very_ long time, and our
// reaction got cleaned up, or we got a observable change
// between render and useEffect
// Re-create the reaction
reactionTrackingRef.current = {
reaction: new Reaction(observerComponentNameFor(baseComponentName), function () {
// We've definitely already been mounted at this point
forceUpdate();
}),
cleanAt: Infinity
};
forceUpdate();
}
return function () { return reactionTrackingRef.current.reaction.dispose(); };
}, []);
// render the original component, but have the

@@ -173,3 +303,3 @@ // reaction track the observables, so that rendering

var exception;
reaction.current.track(function () {
reaction.track(function () {
try {

@@ -183,3 +313,2 @@ rendering = fn();

if (exception) {
reaction.current.dispose();
throw exception; // re-throw any exceptions catched during rendering

@@ -192,3 +321,3 @@ }

function observer(baseComponent, options) {
// The working of observer is explaind step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
// The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
if (isUsingStaticRendering()) {

@@ -269,2 +398,2 @@ return baseComponent;

export { useObservable, useComputed, useDisposable, isUsingStaticRendering, useStaticRendering, observer, useObserver, ObserverComponent as Observer, useForceUpdate };
export { ObserverComponent as Observer, isUsingStaticRendering, observer, useComputed, useDisposable, useForceUpdate, useObservable, useObserver, useStaticRendering };

@@ -112,2 +112,13 @@ (function (global, factory) {

function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {

@@ -131,12 +142,80 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

function printDebugValue(v) {
if (!v.current) {
return "<unknown>";
return mobx.getDependencyTree(v);
}
function createTrackingData(reaction) {
var trackingData = {
cleanAt: Date.now() + CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS,
reaction: reaction
};
return trackingData;
}
/**
* The minimum time before we'll clean up a Reaction created in a render
* for a component that hasn't managed to run its effects. This needs to
* be big enough to ensure that a component won't turn up and have its
* effects run without being re-rendered.
*/
var CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS = 10000;
/**
* The frequency with which we'll check for leaked reactions.
*/
var CLEANUP_TIMER_LOOP_MILLIS = 10000;
/**
* Reactions created by components that have yet to be fully mounted.
*/
var uncommittedReactionRefs = new Set();
/**
* Latest 'uncommitted reactions' cleanup timer handle.
*/
var reactionCleanupHandle;
function ensureCleanupTimerRunning() {
if (reactionCleanupHandle === undefined) {
reactionCleanupHandle = setTimeout(cleanUncommittedReactions, CLEANUP_TIMER_LOOP_MILLIS);
}
return mobx.getDependencyTree(v.current);
}
function scheduleCleanupOfReactionIfLeaked(ref) {
uncommittedReactionRefs.add(ref);
ensureCleanupTimerRunning();
}
function recordReactionAsCommitted(reactionRef) {
uncommittedReactionRefs.delete(reactionRef);
}
/**
* Run by the cleanup timer to dispose any outstanding reactions
*/
function cleanUncommittedReactions() {
var e_1, _a;
reactionCleanupHandle = undefined;
// Loop through all the candidate leaked reactions; those older
// than CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS get tidied.
var now = Date.now();
try {
for (var uncommittedReactionRefs_1 = __values(uncommittedReactionRefs), uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next(); !uncommittedReactionRefs_1_1.done; uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next()) {
var ref = uncommittedReactionRefs_1_1.value;
var tracking = ref.current;
if (tracking) {
if (now >= tracking.cleanAt) {
// It's time to tidy up this leaked reaction.
tracking.reaction.dispose();
ref.current = null;
uncommittedReactionRefs.delete(ref);
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uncommittedReactionRefs_1_1 && !uncommittedReactionRefs_1_1.done && (_a = uncommittedReactionRefs_1.return)) _a.call(uncommittedReactionRefs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (uncommittedReactionRefs.size > 0) {
// We've just finished a round of cleanups but there are still
// some leak candidates outstanding.
ensureCleanupTimerRunning();
}
}
var EMPTY_ARRAY = [];
function useUnmount(fn) {
react.useEffect(function () { return fn; }, EMPTY_ARRAY);
}
function useForceUpdate() {

@@ -151,2 +230,5 @@ var _a = __read(react.useState(0), 2), setTick = _a[1];

var EMPTY_OBJECT = {};
function observerComponentNameFor(baseComponentName) {
return "observer" + baseComponentName;
}
function useObserver(fn, baseComponentName, options) {

@@ -160,12 +242,60 @@ if (baseComponentName === void 0) { baseComponentName = "observed"; }

var forceUpdate = wantedForceUpdateHook();
var reaction = react.useRef(null);
if (!reaction.current) {
reaction.current = new mobx.Reaction("observer(" + baseComponentName + ")", function () {
forceUpdate();
// StrictMode/ConcurrentMode/Suspense may mean that our component is
// rendered and abandoned multiple times, so we need to track leaked
// Reactions.
var reactionTrackingRef = react.useRef(null);
if (!reactionTrackingRef.current) {
// First render for this component (or first time since a previous
// reaction from an abandoned render was disposed).
var newReaction_1 = new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// Observable has changed, meaning we want to re-render
// BUT if we're a component that hasn't yet got to the useEffect()
// stage, we might be a component that _started_ to render, but
// got dropped, and we don't want to make state changes then.
// (It triggers warnings in StrictMode, for a start.)
if (trackingData_1.mounted) {
// We have reached useEffect(), so we're mounted, and can trigger an update
forceUpdate();
}
else {
// We haven't yet reached useEffect(), so we'll need to trigger a re-render
// when (and if) useEffect() arrives. The easiest way to do that is just to
// drop our current reaction and allow useEffect() to recreate it.
newReaction_1.dispose();
reactionTrackingRef.current = null;
}
});
var trackingData_1 = createTrackingData(newReaction_1);
reactionTrackingRef.current = trackingData_1;
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef);
}
var reaction = reactionTrackingRef.current.reaction;
react.useDebugValue(reaction, printDebugValue);
useUnmount(function () {
reaction.current.dispose();
});
react.useEffect(function () {
// Called on first mount only
recordReactionAsCommitted(reactionTrackingRef);
if (reactionTrackingRef.current) {
// Great. We've already got our reaction from our render;
// all we need to do is to record that it's now mounted,
// to allow future observable changes to trigger re-renders
reactionTrackingRef.current.mounted = true;
}
else {
// The reaction we set up in our render has been disposed.
// This is either due to bad timings of renderings, e.g. our
// component was paused for a _very_ long time, and our
// reaction got cleaned up, or we got a observable change
// between render and useEffect
// Re-create the reaction
reactionTrackingRef.current = {
reaction: new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// We've definitely already been mounted at this point
forceUpdate();
}),
cleanAt: Infinity
};
forceUpdate();
}
return function () { return reactionTrackingRef.current.reaction.dispose(); };
}, []);
// render the original component, but have the

@@ -176,3 +306,3 @@ // reaction track the observables, so that rendering

var exception;
reaction.current.track(function () {
reaction.track(function () {
try {

@@ -186,3 +316,2 @@ rendering = fn();

if (exception) {
reaction.current.dispose();
throw exception; // re-throw any exceptions catched during rendering

@@ -195,3 +324,3 @@ }

function observer(baseComponent, options) {
// The working of observer is explaind step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
// The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
if (isUsingStaticRendering()) {

@@ -272,11 +401,11 @@ return baseComponent;

exports.useObservable = useObservable;
exports.Observer = ObserverComponent;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.observer = observer;
exports.useComputed = useComputed;
exports.useDisposable = useDisposable;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.useForceUpdate = useForceUpdate;
exports.useObservable = useObservable;
exports.useObserver = useObserver;
exports.useStaticRendering = useStaticRendering;
exports.observer = observer;
exports.useObserver = useObserver;
exports.Observer = ObserverComponent;
exports.useForceUpdate = useForceUpdate;

@@ -283,0 +412,0 @@ Object.defineProperty(exports, '__esModule', { value: true });

2

dist/index.min.js

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

!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("mobx"),require("react")):"function"==typeof define&&define.amd?define(["exports","mobx","react"],r):r((e=e||self).mobxReact={},e.mobx,e.React)}(this,function(e,r,n){"use strict";if(!n.useState)throw new Error("mobx-react-lite requires React with Hooks support");if(!r.spy)throw new Error("mobx-react-lite requires mobx at least version 4 to be available");var t=function(){};var o=!1;function u(){return o}var i=function(){return(i=Object.assign||function(e){for(var r,n=1,t=arguments.length;n<t;n++)for(var o in r=arguments[n])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e}).apply(this,arguments)};function c(e){return e.current?r.getDependencyTree(e.current):"<unknown>"}var f=[];function a(){var e=function(e,r){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var t,o,u=n.call(e),i=[];try{for(;(void 0===r||r-- >0)&&!(t=u.next()).done;)i.push(t.value)}catch(e){o={error:e}}finally{try{t&&!t.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}return i}(n.useState(0),2)[1];return n.useCallback(function(){e(function(e){return e+1})},[])}var s={};function l(e,t,o){if(void 0===t&&(t="observed"),void 0===o&&(o=s),u())return e();var i,l,p=(o.useForceUpdate||a)(),d=n.useRef(null);if(d.current||(d.current=new r.Reaction("observer("+t+")",function(){p()})),n.useDebugValue(d,c),function(e){n.useEffect(function(){return e},f)}(function(){d.current.dispose()}),d.current.track(function(){try{i=e()}catch(e){l=e}}),l)throw d.current.dispose(),l;return i}var p={$$typeof:!0,render:!0,compare:!0,type:!0};function d(e){var r=e.children,n=e.render,t=r||n;return"function"!=typeof t?null:l(t)}function v(e,r,n,t,o){var u="children"===r?"render":"children",i="function"==typeof e[r],c="function"==typeof e[u];return i&&c?new Error("MobX Observer: Do not use children and render in the same time in`"+n):i||c?null:new Error("Invalid prop `"+o+"` of type `"+typeof e[r]+"` supplied to `"+n+"`, expected `function`.")}d.propTypes={children:v,render:v},d.displayName="Observer",e.useObservable=function(e){var t=n.useRef(null);return t.current||(t.current=r.observable(e)),t.current},e.useComputed=function(e,t){return void 0===t&&(t=[]),n.useMemo(function(){return r.computed(e)},t).get()},e.useDisposable=function(e,r){void 0===r&&(r=[]);var o=n.useRef(null),u=n.useRef(!1);function i(r){if(u.current)return t;if(!o.current){var n=e();if("function"!=typeof n){var i=new Error("generated disposer must be a function");return console.error(i),t}o.current=n}return function(){o.current&&(o.current(),o.current=null),r&&(u.current=!0)}}return n.useEffect(function(){return i(!1)},r),i(!0)},e.isUsingStaticRendering=u,e.useStaticRendering=function(e){o=e},e.observer=function(e,r){if(u())return e;var t,o,c,f=i({forwardRef:!1},r),a=e.displayName||e.name,s=function(r,n){return l(function(){return e(r,n)},a)};return s.displayName=a,t=f.forwardRef?n.memo(n.forwardRef(s)):n.memo(s),o=e,c=t,Object.keys(o).forEach(function(e){o.hasOwnProperty(e)&&!p[e]&&Object.defineProperty(c,e,Object.getOwnPropertyDescriptor(o,e))}),t.displayName=a,t},e.useObserver=l,e.Observer=d,e.useForceUpdate=a,Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("mobx"),require("react")):"function"==typeof define&&define.amd?define(["exports","mobx","react"],r):r((e=e||self).mobxReact={},e.mobx,e.React)}(this,function(e,r,n){"use strict";if(!n.useState)throw new Error("mobx-react-lite requires React with Hooks support");if(!r.spy)throw new Error("mobx-react-lite requires mobx at least version 4 to be available");var t=function(){};var o=!1;function u(){return o}var i=function(){return(i=Object.assign||function(e){for(var r,n=1,t=arguments.length;n<t;n++)for(var o in r=arguments[n])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e}).apply(this,arguments)};function c(e){return r.getDependencyTree(e)}var a,f=1e4,l=1e4,s=new Set;function d(){void 0===a&&(a=setTimeout(p,l))}function p(){var e,r;a=void 0;var n=Date.now();try{for(var t=function(e){var r="function"==typeof Symbol&&e[Symbol.iterator],n=0;return r?r.call(e):{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}}(s),o=t.next();!o.done;o=t.next()){var u=o.value,i=u.current;i&&n>=i.cleanAt&&(i.reaction.dispose(),u.current=null,s.delete(u))}}catch(r){e={error:r}}finally{try{o&&!o.done&&(r=t.return)&&r.call(t)}finally{if(e)throw e.error}}s.size>0&&d()}function v(){var e=function(e,r){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var t,o,u=n.call(e),i=[];try{for(;(void 0===r||r-- >0)&&!(t=u.next()).done;)i.push(t.value)}catch(e){o={error:e}}finally{try{t&&!t.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}return i}(n.useState(0),2)[1];return n.useCallback(function(){e(function(e){return e+1})},[])}var y={};function b(e){return"observer"+e}function m(e,t,o){if(void 0===t&&(t="observed"),void 0===o&&(o=y),u())return e();var i,a=(o.useForceUpdate||v)(),l=n.useRef(null);if(!l.current){var p=new r.Reaction(b(t),function(){m.mounted?a():(p.dispose(),l.current=null)}),m=function(e){return{cleanAt:Date.now()+f,reaction:e}}(p);l.current=m,i=l,s.add(i),d()}var h,w,x=l.current.reaction;if(n.useDebugValue(x,c),n.useEffect(function(){var e;return e=l,s.delete(e),l.current?l.current.mounted=!0:(l.current={reaction:new r.Reaction(b(t),function(){a()}),cleanAt:1/0},a()),function(){return l.current.reaction.dispose()}},[]),x.track(function(){try{h=e()}catch(e){w=e}}),w)throw w;return h}var h={$$typeof:!0,render:!0,compare:!0,type:!0};function w(e){var r=e.children,n=e.render,t=r||n;return"function"!=typeof t?null:m(t)}function x(e,r,n,t,o){var u="children"===r?"render":"children",i="function"==typeof e[r],c="function"==typeof e[u];return i&&c?new Error("MobX Observer: Do not use children and render in the same time in`"+n):i||c?null:new Error("Invalid prop `"+o+"` of type `"+typeof e[r]+"` supplied to `"+n+"`, expected `function`.")}w.propTypes={children:x,render:x},w.displayName="Observer",e.Observer=w,e.isUsingStaticRendering=u,e.observer=function(e,r){if(u())return e;var t,o,c,a=i({forwardRef:!1},r),f=e.displayName||e.name,l=function(r,n){return m(function(){return e(r,n)},f)};return l.displayName=f,t=a.forwardRef?n.memo(n.forwardRef(l)):n.memo(l),o=e,c=t,Object.keys(o).forEach(function(e){o.hasOwnProperty(e)&&!h[e]&&Object.defineProperty(c,e,Object.getOwnPropertyDescriptor(o,e))}),t.displayName=f,t},e.useComputed=function(e,t){return void 0===t&&(t=[]),n.useMemo(function(){return r.computed(e)},t).get()},e.useDisposable=function(e,r){void 0===r&&(r=[]);var o=n.useRef(null),u=n.useRef(!1);function i(r){if(u.current)return t;if(!o.current){var n=e();if("function"!=typeof n){var i=new Error("generated disposer must be a function");return console.error(i),t}o.current=n}return function(){o.current&&(o.current(),o.current=null),r&&(u.current=!0)}}return n.useEffect(function(){return i(!1)},r),i(!0)},e.useForceUpdate=v,e.useObservable=function(e){var t=n.useRef(null);return t.current||(t.current=r.observable(e)),t.current},e.useObserver=m,e.useStaticRendering=function(e){o=e},Object.defineProperty(e,"__esModule",{value:!0})});

@@ -109,2 +109,13 @@ import { spy, observable, computed, getDependencyTree, Reaction } from 'mobx';

function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {

@@ -128,12 +139,80 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

function printDebugValue(v) {
if (!v.current) {
return "<unknown>";
return getDependencyTree(v);
}
function createTrackingData(reaction) {
var trackingData = {
cleanAt: Date.now() + CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS,
reaction: reaction
};
return trackingData;
}
/**
* The minimum time before we'll clean up a Reaction created in a render
* for a component that hasn't managed to run its effects. This needs to
* be big enough to ensure that a component won't turn up and have its
* effects run without being re-rendered.
*/
var CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS = 10000;
/**
* The frequency with which we'll check for leaked reactions.
*/
var CLEANUP_TIMER_LOOP_MILLIS = 10000;
/**
* Reactions created by components that have yet to be fully mounted.
*/
var uncommittedReactionRefs = new Set();
/**
* Latest 'uncommitted reactions' cleanup timer handle.
*/
var reactionCleanupHandle;
function ensureCleanupTimerRunning() {
if (reactionCleanupHandle === undefined) {
reactionCleanupHandle = setTimeout(cleanUncommittedReactions, CLEANUP_TIMER_LOOP_MILLIS);
}
return getDependencyTree(v.current);
}
function scheduleCleanupOfReactionIfLeaked(ref) {
uncommittedReactionRefs.add(ref);
ensureCleanupTimerRunning();
}
function recordReactionAsCommitted(reactionRef) {
uncommittedReactionRefs.delete(reactionRef);
}
/**
* Run by the cleanup timer to dispose any outstanding reactions
*/
function cleanUncommittedReactions() {
var e_1, _a;
reactionCleanupHandle = undefined;
// Loop through all the candidate leaked reactions; those older
// than CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS get tidied.
var now = Date.now();
try {
for (var uncommittedReactionRefs_1 = __values(uncommittedReactionRefs), uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next(); !uncommittedReactionRefs_1_1.done; uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next()) {
var ref = uncommittedReactionRefs_1_1.value;
var tracking = ref.current;
if (tracking) {
if (now >= tracking.cleanAt) {
// It's time to tidy up this leaked reaction.
tracking.reaction.dispose();
ref.current = null;
uncommittedReactionRefs.delete(ref);
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uncommittedReactionRefs_1_1 && !uncommittedReactionRefs_1_1.done && (_a = uncommittedReactionRefs_1.return)) _a.call(uncommittedReactionRefs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (uncommittedReactionRefs.size > 0) {
// We've just finished a round of cleanups but there are still
// some leak candidates outstanding.
ensureCleanupTimerRunning();
}
}
var EMPTY_ARRAY = [];
function useUnmount(fn) {
useEffect(function () { return fn; }, EMPTY_ARRAY);
}
function useForceUpdate() {

@@ -148,2 +227,5 @@ var _a = __read(useState(0), 2), setTick = _a[1];

var EMPTY_OBJECT = {};
function observerComponentNameFor(baseComponentName) {
return "observer" + baseComponentName;
}
function useObserver(fn, baseComponentName, options) {

@@ -157,12 +239,60 @@ if (baseComponentName === void 0) { baseComponentName = "observed"; }

var forceUpdate = wantedForceUpdateHook();
var reaction = useRef(null);
if (!reaction.current) {
reaction.current = new Reaction("observer(" + baseComponentName + ")", function () {
forceUpdate();
// StrictMode/ConcurrentMode/Suspense may mean that our component is
// rendered and abandoned multiple times, so we need to track leaked
// Reactions.
var reactionTrackingRef = useRef(null);
if (!reactionTrackingRef.current) {
// First render for this component (or first time since a previous
// reaction from an abandoned render was disposed).
var newReaction_1 = new Reaction(observerComponentNameFor(baseComponentName), function () {
// Observable has changed, meaning we want to re-render
// BUT if we're a component that hasn't yet got to the useEffect()
// stage, we might be a component that _started_ to render, but
// got dropped, and we don't want to make state changes then.
// (It triggers warnings in StrictMode, for a start.)
if (trackingData_1.mounted) {
// We have reached useEffect(), so we're mounted, and can trigger an update
forceUpdate();
}
else {
// We haven't yet reached useEffect(), so we'll need to trigger a re-render
// when (and if) useEffect() arrives. The easiest way to do that is just to
// drop our current reaction and allow useEffect() to recreate it.
newReaction_1.dispose();
reactionTrackingRef.current = null;
}
});
var trackingData_1 = createTrackingData(newReaction_1);
reactionTrackingRef.current = trackingData_1;
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef);
}
var reaction = reactionTrackingRef.current.reaction;
useDebugValue(reaction, printDebugValue);
useUnmount(function () {
reaction.current.dispose();
});
useEffect(function () {
// Called on first mount only
recordReactionAsCommitted(reactionTrackingRef);
if (reactionTrackingRef.current) {
// Great. We've already got our reaction from our render;
// all we need to do is to record that it's now mounted,
// to allow future observable changes to trigger re-renders
reactionTrackingRef.current.mounted = true;
}
else {
// The reaction we set up in our render has been disposed.
// This is either due to bad timings of renderings, e.g. our
// component was paused for a _very_ long time, and our
// reaction got cleaned up, or we got a observable change
// between render and useEffect
// Re-create the reaction
reactionTrackingRef.current = {
reaction: new Reaction(observerComponentNameFor(baseComponentName), function () {
// We've definitely already been mounted at this point
forceUpdate();
}),
cleanAt: Infinity
};
forceUpdate();
}
return function () { return reactionTrackingRef.current.reaction.dispose(); };
}, []);
// render the original component, but have the

@@ -173,3 +303,3 @@ // reaction track the observables, so that rendering

var exception;
reaction.current.track(function () {
reaction.track(function () {
try {

@@ -183,3 +313,2 @@ rendering = fn();

if (exception) {
reaction.current.dispose();
throw exception; // re-throw any exceptions catched during rendering

@@ -192,3 +321,3 @@ }

function observer(baseComponent, options) {
// The working of observer is explaind step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
// The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
if (isUsingStaticRendering()) {

@@ -269,2 +398,2 @@ return baseComponent;

export { useObservable, useComputed, useDisposable, isUsingStaticRendering, useStaticRendering, observer, useObserver, ObserverComponent as Observer, useForceUpdate };
export { ObserverComponent as Observer, isUsingStaticRendering, observer, useComputed, useDisposable, useForceUpdate, useObservable, useObserver, useStaticRendering };

@@ -113,2 +113,13 @@ 'use strict';

function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {

@@ -132,12 +143,80 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

function printDebugValue(v) {
if (!v.current) {
return "<unknown>";
return mobx.getDependencyTree(v);
}
function createTrackingData(reaction) {
var trackingData = {
cleanAt: Date.now() + CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS,
reaction: reaction
};
return trackingData;
}
/**
* The minimum time before we'll clean up a Reaction created in a render
* for a component that hasn't managed to run its effects. This needs to
* be big enough to ensure that a component won't turn up and have its
* effects run without being re-rendered.
*/
var CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS = 10000;
/**
* The frequency with which we'll check for leaked reactions.
*/
var CLEANUP_TIMER_LOOP_MILLIS = 10000;
/**
* Reactions created by components that have yet to be fully mounted.
*/
var uncommittedReactionRefs = new Set();
/**
* Latest 'uncommitted reactions' cleanup timer handle.
*/
var reactionCleanupHandle;
function ensureCleanupTimerRunning() {
if (reactionCleanupHandle === undefined) {
reactionCleanupHandle = setTimeout(cleanUncommittedReactions, CLEANUP_TIMER_LOOP_MILLIS);
}
return mobx.getDependencyTree(v.current);
}
function scheduleCleanupOfReactionIfLeaked(ref) {
uncommittedReactionRefs.add(ref);
ensureCleanupTimerRunning();
}
function recordReactionAsCommitted(reactionRef) {
uncommittedReactionRefs.delete(reactionRef);
}
/**
* Run by the cleanup timer to dispose any outstanding reactions
*/
function cleanUncommittedReactions() {
var e_1, _a;
reactionCleanupHandle = undefined;
// Loop through all the candidate leaked reactions; those older
// than CLEANUP_LEAKED_REACTIONS_AFTER_MILLIS get tidied.
var now = Date.now();
try {
for (var uncommittedReactionRefs_1 = __values(uncommittedReactionRefs), uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next(); !uncommittedReactionRefs_1_1.done; uncommittedReactionRefs_1_1 = uncommittedReactionRefs_1.next()) {
var ref = uncommittedReactionRefs_1_1.value;
var tracking = ref.current;
if (tracking) {
if (now >= tracking.cleanAt) {
// It's time to tidy up this leaked reaction.
tracking.reaction.dispose();
ref.current = null;
uncommittedReactionRefs.delete(ref);
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uncommittedReactionRefs_1_1 && !uncommittedReactionRefs_1_1.done && (_a = uncommittedReactionRefs_1.return)) _a.call(uncommittedReactionRefs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (uncommittedReactionRefs.size > 0) {
// We've just finished a round of cleanups but there are still
// some leak candidates outstanding.
ensureCleanupTimerRunning();
}
}
var EMPTY_ARRAY = [];
function useUnmount(fn) {
react.useEffect(function () { return fn; }, EMPTY_ARRAY);
}
function useForceUpdate() {

@@ -152,2 +231,5 @@ var _a = __read(react.useState(0), 2), setTick = _a[1];

var EMPTY_OBJECT = {};
function observerComponentNameFor(baseComponentName) {
return "observer" + baseComponentName;
}
function useObserver(fn, baseComponentName, options) {

@@ -161,12 +243,60 @@ if (baseComponentName === void 0) { baseComponentName = "observed"; }

var forceUpdate = wantedForceUpdateHook();
var reaction = react.useRef(null);
if (!reaction.current) {
reaction.current = new mobx.Reaction("observer(" + baseComponentName + ")", function () {
forceUpdate();
// StrictMode/ConcurrentMode/Suspense may mean that our component is
// rendered and abandoned multiple times, so we need to track leaked
// Reactions.
var reactionTrackingRef = react.useRef(null);
if (!reactionTrackingRef.current) {
// First render for this component (or first time since a previous
// reaction from an abandoned render was disposed).
var newReaction_1 = new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// Observable has changed, meaning we want to re-render
// BUT if we're a component that hasn't yet got to the useEffect()
// stage, we might be a component that _started_ to render, but
// got dropped, and we don't want to make state changes then.
// (It triggers warnings in StrictMode, for a start.)
if (trackingData_1.mounted) {
// We have reached useEffect(), so we're mounted, and can trigger an update
forceUpdate();
}
else {
// We haven't yet reached useEffect(), so we'll need to trigger a re-render
// when (and if) useEffect() arrives. The easiest way to do that is just to
// drop our current reaction and allow useEffect() to recreate it.
newReaction_1.dispose();
reactionTrackingRef.current = null;
}
});
var trackingData_1 = createTrackingData(newReaction_1);
reactionTrackingRef.current = trackingData_1;
scheduleCleanupOfReactionIfLeaked(reactionTrackingRef);
}
var reaction = reactionTrackingRef.current.reaction;
react.useDebugValue(reaction, printDebugValue);
useUnmount(function () {
reaction.current.dispose();
});
react.useEffect(function () {
// Called on first mount only
recordReactionAsCommitted(reactionTrackingRef);
if (reactionTrackingRef.current) {
// Great. We've already got our reaction from our render;
// all we need to do is to record that it's now mounted,
// to allow future observable changes to trigger re-renders
reactionTrackingRef.current.mounted = true;
}
else {
// The reaction we set up in our render has been disposed.
// This is either due to bad timings of renderings, e.g. our
// component was paused for a _very_ long time, and our
// reaction got cleaned up, or we got a observable change
// between render and useEffect
// Re-create the reaction
reactionTrackingRef.current = {
reaction: new mobx.Reaction(observerComponentNameFor(baseComponentName), function () {
// We've definitely already been mounted at this point
forceUpdate();
}),
cleanAt: Infinity
};
forceUpdate();
}
return function () { return reactionTrackingRef.current.reaction.dispose(); };
}, []);
// render the original component, but have the

@@ -177,3 +307,3 @@ // reaction track the observables, so that rendering

var exception;
reaction.current.track(function () {
reaction.track(function () {
try {

@@ -187,3 +317,2 @@ rendering = fn();

if (exception) {
reaction.current.dispose();
throw exception; // re-throw any exceptions catched during rendering

@@ -196,3 +325,3 @@ }

function observer(baseComponent, options) {
// The working of observer is explaind step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
// The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
if (isUsingStaticRendering()) {

@@ -273,10 +402,10 @@ return baseComponent;

exports.useObservable = useObservable;
exports.Observer = ObserverComponent;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.observer = observer;
exports.useComputed = useComputed;
exports.useDisposable = useDisposable;
exports.isUsingStaticRendering = isUsingStaticRendering;
exports.useForceUpdate = useForceUpdate;
exports.useObservable = useObservable;
exports.useObserver = useObserver;
exports.useStaticRendering = useStaticRendering;
exports.observer = observer;
exports.useObserver = useObserver;
exports.Observer = ObserverComponent;
exports.useForceUpdate = useForceUpdate;

@@ -8,2 +8,2 @@ /// <reference types="react" />

}): React.MemoExoticComponent<React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<TRef>>>;
export declare function observer<P extends object>(baseComponent: React.FunctionComponent<P>, options?: IObserverOptions): React.NamedExoticComponent<P>;
export declare function observer<P extends object>(baseComponent: React.FunctionComponent<P>, options?: IObserverOptions): React.FunctionComponent<P>;

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

/// <reference types="react" />
import { Reaction } from "mobx";
export declare function printDebugValue(v: React.MutableRefObject<Reaction | null>): "<unknown>" | import("mobx").IDependencyTree;
export declare function printDebugValue(v: Reaction): import("mobx").IDependencyTree;

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

export declare function useUnmount(fn: () => void): void;
export declare function useForceUpdate(): () => void;
{
"name": "mobx-react-lite",
"version": "1.2.0",
"version": "2.0.0-alpha.0",
"description": "Lightweight React bindings for MobX based on React 16.8 and Hooks",

@@ -37,31 +37,31 @@ "main": "dist/index.js",

"@types/jest": "24.0.11",
"@types/node": "11.11.8",
"@types/node": "11.13.8",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@types/react-dom": "16.8.4",
"coveralls": "3.0.3",
"husky": "1.3.1",
"jest": "24.5.0",
"husky": "2.1.0",
"jest": "24.7.1",
"jest-dom": "3.1.3",
"jest-environment-jsdom": "24.5.0",
"jest-environment-jsdom": "24.7.1",
"jest-mock-console": "0.4.2",
"lint-staged": "8.1.5",
"lodash": "4.17.11",
"mobx": "5.9.0",
"prettier": "1.16.4",
"react": "16.8.5",
"react-dom": "16.8.5",
"react-testing-library": "6.0.2",
"mobx": "5.9.4",
"prettier": "1.17.0",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-testing-library": "7.0.0",
"rimraf": "2.6.3",
"rollup": "1.7.3",
"rollup": "1.10.1",
"rollup-plugin-alias": "1.5.1",
"rollup-plugin-commonjs": "9.2.2",
"rollup-plugin-commonjs": "9.3.4",
"rollup-plugin-filesize": "6.0.1",
"rollup-plugin-node-resolve": "4.0.1",
"rollup-plugin-replace": "2.1.1",
"rollup-plugin-node-resolve": "4.2.3",
"rollup-plugin-replace": "2.2.0",
"rollup-plugin-terser": "4.0.4",
"rollup-plugin-typescript2": "0.20.1",
"ts-jest": "24.0.0",
"tslint": "5.14.0",
"rollup-plugin-typescript2": "0.21.0",
"ts-jest": "24.0.2",
"tslint": "5.16.0",
"tslint-config-prettier": "1.18.0",
"typescript": "3.3.4000"
"typescript": "3.4.5"
},

@@ -68,0 +68,0 @@ "keywords": [

@@ -27,3 +27,2 @@ # mobx-react-lite <!-- omit in toc -->

- [Why no Provider/inject?](#why-no-providerinject)
- [What about smart/dumb components?](#what-about-smartdumb-components)

@@ -34,3 +33,3 @@ ## API documentation

`Observer` is a React component, which applies `observer` to an anonymous region in your component.
`Observer` is a React component, which applies observer to an anonymous region in your component.
It takes as children a single, argumentless function which should return exactly one React component.

@@ -309,50 +308,1 @@ The rendering in the function will be tracked and automatically re-rendered when needed.

```
## What about smart/dumb components?
The React hooks don't force anyone to suddenly have a state inside a _dumb component_ that is supposed to only render stuff. You can separate your concerns in a similar fashion.
```tsx
import { createSelector } from "react-selector-hooks"
const userSelector = createSelector(({ user }) => ({
name: user.name,
age: user.age
}))
function UiComponent({ name, age }) {
return (
<div>
<div>Name: {name}</div>
<div>Age: {age}</div>
</div>
)
}
export default () => {
// you may extract these two lines into a custom hook
const store = useContext(StoreContext)
const data = userSelector(store)
return UiComponent({ ...data })
// perhaps wrap it inside observer in here?
return observer(UiComponent({ ...data }))
}
```
It may look a bit more verbose than a _classic_ inject, but there is nothing stopping you to make your own `inject` HOC which is so much easier since everything is just a function.
```tsx
// make universal HOC
const inject = (useSelector, baseComponent) =>
React.useMemo(props => {
const store = useContext(StoreContext)
const selected = useSelector(store)
return baseComponent({ ...selected, ...props })
})
// use the HOC with a selector
export default inject(userSelector, UiComponent)
```
{
"extends": [
"config:base"
]
],
"automerge": true,
"automergeType": "branch",
"major": {
"automerge": false
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc