Skip to content

Commit 2e07940

Browse files
committed
feat: support parentPopupState in render props, fix unmounted issues
1 parent e15a377 commit 2e07940

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/hooks.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow
22

3-
import { useState } from 'react'
3+
import { useState, useRef, useEffect } from 'react'
44

55
if (!useState) {
66
throw new Error(
@@ -19,6 +19,7 @@ import {
1919
bindPopper,
2020
type Variant,
2121
type PopupState,
22+
type CoreState,
2223
} from './core'
2324

2425
export { bindTrigger, bindToggle, bindHover, bindMenu, bindPopover, bindPopper }
@@ -34,7 +35,16 @@ export function usePopupState({
3435
variant: Variant,
3536
}): PopupState {
3637
const [state, _setState] = useState(initCoreState)
37-
const setState = nextState => _setState({ ...state, ...nextState })
38+
const isMounted = useRef(true)
39+
useEffect(
40+
() => () => {
41+
isMounted.current = false
42+
},
43+
[]
44+
)
45+
const setState = (nextState: $Shape<CoreState>) => {
46+
if (isMounted.current) _setState({ ...state, ...nextState })
47+
}
3848

3949
return createPopupState({
4050
state,

src/index.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ export type Props = {
2424
popupId?: string,
2525
children: (props: InjectedProps) => ?React.Node,
2626
variant: Variant,
27+
parentPopupState?: ?InjectedProps,
2728
}
2829

2930
export default class PopupState extends React.Component<Props, CoreState> {
3031
state: CoreState = initCoreState
3132

33+
_mounted: boolean = true
34+
3235
static propTypes = {
3336
/**
3437
* The render function.
@@ -64,16 +67,29 @@ export default class PopupState extends React.Component<Props, CoreState> {
6467
* component.
6568
*/
6669
variant: PropTypes.oneOf(['popover', 'popper']).isRequired,
70+
/**
71+
*
72+
*/
73+
parentPopupState: PropTypes.object,
74+
}
75+
76+
componentWillUnmount() {
77+
this._mounted = false
78+
}
79+
80+
_setStateIfMounted = (state: $Shape<CoreState>) => {
81+
if (this._mounted) this.setState(state)
6782
}
6883

6984
render(): React.Node | null {
70-
const { children, popupId, variant } = this.props
85+
const { children, popupId, variant, parentPopupState } = this.props
7186

7287
const popupState = createPopupState({
7388
state: this.state,
74-
setState: state => this.setState(state),
89+
setState: this._setStateIfMounted,
7590
popupId,
7691
variant,
92+
parentPopupState,
7793
})
7894

7995
const result = children(popupState)

0 commit comments

Comments
 (0)