Skip to content

Commit aa9d975

Browse files
committed
add useClassImperativeHandle hook
1 parent 2374bb4 commit aa9d975

File tree

6 files changed

+103
-2
lines changed

6 files changed

+103
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ v. 0.4.0
44
* useClassEffect - fix ConcurrentMode
55
* hooks stack counter - fix ConcurrentMode
66
* build optimization - removed babel slicedToArray
7+
* add useClassImperativeHandle hook
78

89
v. 0.3.6
910
-----------

dist/index.esm.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,36 @@ useClassContext.create = function (name) {
408408
return createNamedHook(name, useClassContextKey);
409409
};
410410

411+
function useClassImperativeHandle(ref, create, deps) {
412+
invariant(typeof create === 'function', "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: ".concat(create !== null ? _typeof(create) : 'null'));
413+
invariant(deps === null || deps === undefined || Array.isArray(deps), 'Hook received a final argument that is not an array!');
414+
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; // eslint-disable-next-line consistent-return
415+
416+
useClassEffect(function () {
417+
if (typeof ref === 'function') {
418+
var refCallback = ref;
419+
refCallback(create()); // eslint-disable-next-line func-names
420+
421+
return function () {
422+
refCallback(null);
423+
};
424+
}
425+
426+
if (ref !== null && ref !== undefined) {
427+
var refObject = ref;
428+
invariant(refObject.hasOwnProperty('current'), "Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: an object with keys {".concat(Object.keys(refObject).join(', '), "}"));
429+
refObject.current = create(); // eslint-disable-next-line func-names
430+
431+
return function () {
432+
refObject.current = null;
433+
};
434+
}
435+
}, effectDeps);
436+
}
437+
411438
/**
412439
* https://github.com/salvoravida/react-class-hooks
413440
*/
414441
var useClassLayoutEffect = useClassEffect;
415442

416-
export { refCallback, useClassCallback, useClassContext, useClassEffect, useClassLayoutEffect, useClassMemo, useClassReducer, useClassRef, useClassState };
443+
export { refCallback, useClassCallback, useClassContext, useClassEffect, useClassImperativeHandle, useClassLayoutEffect, useClassMemo, useClassReducer, useClassRef, useClassState };

dist/index.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,33 @@ useClassContext.create = function (name) {
414414
return createNamedHook(name, useClassContextKey);
415415
};
416416

417+
function useClassImperativeHandle(ref, create, deps) {
418+
invariant(typeof create === 'function', "Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: ".concat(create !== null ? _typeof(create) : 'null'));
419+
invariant(deps === null || deps === undefined || Array.isArray(deps), 'Hook received a final argument that is not an array!');
420+
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; // eslint-disable-next-line consistent-return
421+
422+
useClassEffect(function () {
423+
if (typeof ref === 'function') {
424+
var refCallback = ref;
425+
refCallback(create()); // eslint-disable-next-line func-names
426+
427+
return function () {
428+
refCallback(null);
429+
};
430+
}
431+
432+
if (ref !== null && ref !== undefined) {
433+
var refObject = ref;
434+
invariant(refObject.hasOwnProperty('current'), "Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: an object with keys {".concat(Object.keys(refObject).join(', '), "}"));
435+
refObject.current = create(); // eslint-disable-next-line func-names
436+
437+
return function () {
438+
refObject.current = null;
439+
};
440+
}
441+
}, effectDeps);
442+
}
443+
417444
/**
418445
* https://github.com/salvoravida/react-class-hooks
419446
*/
@@ -423,6 +450,7 @@ exports.refCallback = refCallback;
423450
exports.useClassCallback = useClassCallback;
424451
exports.useClassContext = useClassContext;
425452
exports.useClassEffect = useClassEffect;
453+
exports.useClassImperativeHandle = useClassImperativeHandle;
426454
exports.useClassLayoutEffect = useClassLayoutEffect;
427455
exports.useClassMemo = useClassMemo;
428456
exports.useClassReducer = useClassReducer;

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/useClassImperativeHandle.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import invariant from 'tiny-invariant';
2+
import { useClassEffect } from './useClassEffect';
3+
4+
export function useClassImperativeHandle(ref, create, deps) {
5+
invariant(
6+
typeof create === 'function',
7+
`Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: ${
8+
create !== null ? typeof create : 'null'
9+
}`,
10+
);
11+
invariant(
12+
deps === null || deps === undefined || Array.isArray(deps),
13+
'Hook received a final argument that is not an array!',
14+
);
15+
16+
const effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
17+
18+
// eslint-disable-next-line consistent-return
19+
useClassEffect(() => {
20+
if (typeof ref === 'function') {
21+
const refCallback = ref;
22+
refCallback(create());
23+
// eslint-disable-next-line func-names
24+
return function () {
25+
refCallback(null);
26+
};
27+
}
28+
if (ref !== null && ref !== undefined) {
29+
const refObject = ref;
30+
invariant(
31+
refObject.hasOwnProperty('current'),
32+
`Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: an object with keys {${Object.keys(
33+
refObject,
34+
).join(', ')}}`,
35+
);
36+
refObject.current = create();
37+
// eslint-disable-next-line func-names
38+
return function () {
39+
refObject.current = null;
40+
};
41+
}
42+
}, effectDeps);
43+
}

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useClassCallback } from './core/useClassCallback';
99
import { useClassReducer } from './core/useClassReducer';
1010
import { useClassRef, refCallback } from './core/useClassRef';
1111
import { useClassContext } from './core/useClassContext';
12+
import { useClassImperativeHandle } from './core/useClassImperativeHandle';
1213

1314
const useClassLayoutEffect = useClassEffect;
1415

@@ -22,4 +23,5 @@ export {
2223
useClassRef,
2324
refCallback,
2425
useClassContext,
26+
useClassImperativeHandle,
2527
};

0 commit comments

Comments
 (0)