Skip to content

Commit 1226aae

Browse files
authored
Support ref unmounting on imperative handles (#4625)
1 parent a1ff5f3 commit 1226aae

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

hooks/src/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,11 @@ export function useImperativeHandle(ref, createHandle, args) {
320320
useLayoutEffect(
321321
() => {
322322
if (typeof ref == 'function') {
323-
ref(createHandle());
324-
return () => ref(null);
323+
const result = ref(createHandle());
324+
return () => {
325+
ref(null);
326+
if (result && typeof result == 'function') result();
327+
};
325328
} else if (ref) {
326329
ref.current = createHandle();
327330
return () => (ref.current = null);

hooks/test/browser/useImperativeHandle.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,30 @@ describe('useImperativeHandle', () => {
3535
expect(ref.current.test()).to.equal('test');
3636
});
3737

38+
it('Calls ref unmounting function', () => {
39+
let ref;
40+
const unmount = sinon.spy();
41+
42+
function Comp() {
43+
useImperativeHandle(
44+
r => {
45+
ref = r;
46+
return unmount;
47+
},
48+
() => ({ test: () => 'test' }),
49+
[]
50+
);
51+
return <p>Test</p>;
52+
}
53+
54+
render(<Comp />, scratch);
55+
expect(ref).to.have.property('test');
56+
expect(ref.test()).to.equal('test');
57+
render(null, scratch);
58+
expect(unmount).to.be.calledOnce;
59+
expect(ref).to.equal(null);
60+
});
61+
3862
it('calls createHandle after every render by default', () => {
3963
let ref,
4064
createHandleSpy = sinon.spy();

0 commit comments

Comments
 (0)