Skip to content

Commit be566a6

Browse files
authored
fix: do not remove host node when mounted node changes (#30)
1 parent 87a8f00 commit be566a6

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

src/StickPortal.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import React, {
1010
useEffect,
1111
useLayoutEffect,
1212
useRef,
13-
useState
13+
useState,
1414
} from 'react'
1515
import { createPortal } from 'react-dom'
1616

@@ -37,6 +37,7 @@ function StickPortal(
3737
const nodeRef = useRef()
3838
const [top, setTop] = useState(0)
3939
const [left, setLeft] = useState(0)
40+
const [visible, setVisible] = useState(!!node)
4041

4142
const [host, hostParent] = useHost(transportTo)
4243

@@ -46,15 +47,19 @@ function StickPortal(
4647
}
4748
}, [onReposition, top, left])
4849

50+
useEffect(() => {
51+
setVisible(!!node)
52+
}, [node])
53+
4954
useLayoutEffect(() => {
50-
if (node) {
55+
if (visible) {
5156
hostParent.appendChild(host)
5257

5358
return () => {
5459
hostParent.removeChild(host)
5560
}
5661
}
57-
}, [host, hostParent, node])
62+
}, [host, hostParent, visible])
5863

5964
const measure = useCallback(() => {
6065
if (!nodeRef.current) {
@@ -89,7 +94,7 @@ function StickPortal(
8994
<Component
9095
{...style}
9196
{...rest}
92-
ref={node => {
97+
ref={(node) => {
9398
if (typeof ref === 'function') {
9499
ref(node)
95100
} else {
@@ -113,7 +118,7 @@ function StickPortal(
113118
// $FlowFixMe
114119
...nodeStyle,
115120
top,
116-
left
121+
left,
117122
}}
118123
>
119124
{node}

tests/updates.test.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import expect from 'expect'
22
import React, { cloneElement } from 'react'
33
import { render as renderBase, unmountComponentAtNode } from 'react-dom'
4+
import { act } from 'react-dom/test-utils'
45
import Stick from 'src/'
56

67
describe('updates', () => {
@@ -12,18 +13,21 @@ describe('updates', () => {
1213
// wrap render to invoke callback only after the node has actually been mounted
1314
const render = (stick, host, callback) => {
1415
let called = false
15-
renderBase(
16-
<div style={{ width: 10, height: 10 }}>
17-
{cloneElement(stick, {
18-
node:
19-
stick.props.node &&
20-
cloneElement(stick.props.node, {
21-
ref: el => !!el && !called && window.setTimeout(callback, 1),
22-
}),
23-
})}
24-
</div>,
25-
host
26-
)
16+
17+
act(() => {
18+
renderBase(
19+
<div style={{ width: 10, height: 10 }}>
20+
{cloneElement(stick, {
21+
node:
22+
stick.props.node &&
23+
cloneElement(stick.props.node, {
24+
ref: (el) => !!el && !called && window.setTimeout(callback, 1),
25+
}),
26+
})}
27+
</div>,
28+
host
29+
)
30+
})
2731
}
2832

2933
beforeEach(() => {
@@ -36,7 +40,7 @@ describe('updates', () => {
3640
document.body.removeChild(host)
3741
})
3842

39-
it('should work if the node is only provided after the initial mount', done => {
43+
it('should work if the node is only provided after the initial mount', (done) => {
4044
render(<Stick position="middle right">{anchor}</Stick>, host)
4145
render(
4246
<Stick position="middle right" node={node}>
@@ -53,7 +57,7 @@ describe('updates', () => {
5357
)
5458
})
5559

56-
it('should unmount node container if no node is passed anymore', done => {
60+
it('should unmount node container if no node is passed anymore', (done) => {
5761
render(<Stick node={node}>{anchor}</Stick>, host, () => {
5862
const bodyChildrenCountWithStick = document.body.childElementCount
5963
render(<Stick>{anchor}</Stick>, host)
@@ -67,7 +71,7 @@ describe('updates', () => {
6771
})
6872
})
6973

70-
it('should correctly apply `sameWidth` if set after initial mount', done => {
74+
it('should correctly apply `sameWidth` if set after initial mount', (done) => {
7175
render(<Stick node={node}>{anchor}</Stick>, host, () => {
7276
render(
7377
<Stick node={node} sameWidth>
@@ -86,7 +90,7 @@ describe('updates', () => {
8690
})
8791
})
8892

89-
it('should correctly handle clearing of `sameWidth` after initial mount', done => {
93+
it('should correctly handle clearing of `sameWidth` after initial mount', (done) => {
9094
render(
9195
<Stick sameWidth node={node}>
9296
{anchor}
@@ -103,7 +107,7 @@ describe('updates', () => {
103107
)
104108
})
105109

106-
it('should handle switching to `updateOnAnimationFrame` correctly', done => {
110+
it('should handle switching to `updateOnAnimationFrame` correctly', (done) => {
107111
render(
108112
<Stick node={node} position="middle right">
109113
{anchor}
@@ -127,7 +131,7 @@ describe('updates', () => {
127131
)
128132
})
129133

130-
it('should handle switching back from `updateOnAnimationFrame` correctly', done => {
134+
it('should handle switching back from `updateOnAnimationFrame` correctly', (done) => {
131135
render(
132136
<Stick node={node} position="middle right" updateOnAnimationFrame>
133137
{anchor}

0 commit comments

Comments
 (0)