Skip to content

Commit 0ffa09d

Browse files
committed
Document and improve API for unmountIfNoConsumers
1 parent 949aada commit 0ffa09d

File tree

6 files changed

+28
-5
lines changed

6 files changed

+28
-5
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,19 @@ const App = () => {
297297

298298
```
299299

300+
### Unmounting hooks when there are no consumers
301+
302+
You can pass the last optional parameter `options` to the `singletonHook` to
303+
configure if the hook should be unmounted when no one consumes it:
304+
```js
305+
306+
const useHook = singletonHook(
307+
initVal,
308+
() => { /*hook body*/ },
309+
{ unmountIfNoConsumers: true }
310+
);
311+
```
312+
300313
## React Native
301314
To use this library with react-native you always have to mount `SingletonHooksContainer` manually.
302315
See how to do it in example: *use react-redux (or any other context) inside singletonHook*

index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ export = ReactSingletonHook;
33
export as namespace ReactSingletonHook;
44

55
declare namespace ReactSingletonHook {
6-
function singletonHook<ValueType>(initialState: ValueType | (() => ValueType), useHook: () => ValueType): () => ValueType;
6+
function singletonHook<ValueType>(
7+
initialState: ValueType | (() => ValueType),
8+
useHook: () => ValueType,
9+
options?: {
10+
unmountIfNoConsumers?: boolean
11+
}
12+
): () => ValueType;
13+
714
function SingletonHooksContainer(): any;
815
}

src/components/SingletonHooksContainer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let mountQueue = [];
1111
const mountIntoContainerDefault = (item) => {
1212
mountQueue.push(item);
1313
return () => {
14-
throw new Error('damn');
14+
throw new Error('Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true');
1515
// mountQueue = mountQueue.filter(i => i !== item);
1616
};
1717
};

src/singletonHook.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import { useEffect, useState } from 'react';
22
import { addHook } from './components/SingletonHooksContainer';
33
import { batch } from './utils/env';
44

5-
export const singletonHook = (initValue, useHookBody, unmountIfNoConsumers = false) => {
5+
export const singletonHook = (initValue, useHookBody, options = {}) => {
66
let mounted = false;
77
let removeHook = undefined;
88
let initStateCalculated = false;
99
let lastKnownState = undefined;
1010
let consumers = [];
11+
let {
12+
unmountIfNoConsumers = false
13+
} = options;
1114

1215
const applyStateChange = (newState) => {
1316
lastKnownState = newState;

test/integration/integration.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ describe('singletonHook', () => {
112112
it('unmounts hook if no consumers', () => {
113113
const unmountCallback = jest.fn();
114114
const initVal = 'initVal';
115-
const useHook = singletonHook(initVal, () => useEffect(() => unmountCallback), true);
115+
const useHook = singletonHook(initVal, () => useEffect(() => unmountCallback), { unmountIfNoConsumers: true });
116116

117117
const Tmp = () => {
118118
useHook();

test/react-native/native.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ describe('singletonHook', () => {
101101
it('unmounts hook if no consumers', () => {
102102
const unmountCallback = jest.fn();
103103
const initVal = 'initVal';
104-
const useHook = singletonHook(initVal, () => useEffect(() => unmountCallback), true);
104+
const useHook = singletonHook(initVal, () => useEffect(() => unmountCallback), { unmountIfNoConsumers: true });
105105

106106
const Tmp = () => {
107107
useHook();

0 commit comments

Comments
 (0)