Skip to content

Commit ad47a6b

Browse files
authored
chore(TransitionablePortal): remove usage of UNSAFE_* methods (#3966)
* chore(TransitionablePortal): remove usage of UNSAFE_* methods * make behavior acc * fix remaining issue * remove only
1 parent 9513785 commit ad47a6b

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

src/addons/TransitionablePortal/TransitionablePortal.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,28 @@ export default class TransitionablePortal extends Component {
6464
},
6565
}
6666

67-
constructor(props) {
68-
super(props)
69-
70-
this.state = {
71-
portalOpen: props.open,
72-
}
73-
}
67+
state = {}
7468

7569
// ----------------------------------------
7670
// Lifecycle
7771
// ----------------------------------------
7872

79-
// eslint-disable-next-line camelcase
80-
UNSAFE_componentWillReceiveProps({ open }) {
81-
debug('componentWillReceiveProps()', { open })
73+
static getDerivedStateFromProps(props, state) {
74+
// This is definitely a hack :(
75+
//
76+
// It's coupled with handlePortalClose() for force set the state of `portalOpen` omitting
77+
// props.open. It's related to implementation of the component itself as `onClose()` will be
78+
// called after a transition will end.
79+
// https://github.com/Semantic-Org/Semantic-UI-React/issues/2382
80+
if (state.portalOpen === -1) {
81+
return { portalOpen: false }
82+
}
8283

83-
this.setState({ portalOpen: open })
84+
if (_.isUndefined(props.open)) {
85+
return null
86+
}
87+
88+
return { portalOpen: props.open }
8489
}
8590

8691
// ----------------------------------------
@@ -90,7 +95,7 @@ export default class TransitionablePortal extends Component {
9095
handlePortalClose = () => {
9196
debug('handlePortalClose()')
9297

93-
this.setState({ portalOpen: false })
98+
this.setState({ portalOpen: -1 })
9499
}
95100

96101
handlePortalOpen = () => {
@@ -129,7 +134,7 @@ export default class TransitionablePortal extends Component {
129134

130135
render() {
131136
debug('render()', this.state)
132-
137+
// console.log('render', this.state)
133138
const { children, transition } = this.props
134139
const { portalOpen, transitionVisible } = this.state
135140

test/specs/addons/TransitionablePortal/TransitionablePortal-test.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('TransitionablePortal', () => {
4343
})
4444
})
4545

46-
describe('componentWillReceiveProps', () => {
46+
describe('getDerivedStateFromProps', () => {
4747
it('passes `open` prop to `portalOpen` when defined', () => {
4848
wrapperMount(<TransitionablePortal {...requiredProps} />)
4949

@@ -64,13 +64,13 @@ describe('TransitionablePortal', () => {
6464
describe('onClose', () => {
6565
it('is called with (null, data) when Portal closes', (done) => {
6666
const onClose = sandbox.spy()
67-
const trigger = <button />
67+
6868
wrapperMount(
6969
<TransitionablePortal
7070
{...requiredProps}
7171
onClose={onClose}
7272
transition={quickTransition}
73-
trigger={trigger}
73+
trigger={<button />}
7474
/>,
7575
)
7676

@@ -84,9 +84,12 @@ describe('TransitionablePortal', () => {
8484
})
8585

8686
it('changes `portalOpen` to false', () => {
87-
const trigger = <button />
8887
wrapperMount(
89-
<TransitionablePortal {...requiredProps} transition={quickTransition} trigger={trigger} />,
88+
<TransitionablePortal
89+
{...requiredProps}
90+
transition={quickTransition}
91+
trigger={<button />}
92+
/>,
9093
)
9194

9295
wrapper.find('button').simulate('click')
@@ -125,19 +128,16 @@ describe('TransitionablePortal', () => {
125128
describe('onOpen', () => {
126129
it('is called with (null, data) when Portal opens', () => {
127130
const onOpen = sandbox.spy()
128-
const trigger = <button />
129131

130-
wrapperMount(<TransitionablePortal {...requiredProps} onOpen={onOpen} trigger={trigger} />)
131-
.find('button')
132-
.simulate('click')
132+
wrapperMount(<TransitionablePortal {...requiredProps} onOpen={onOpen} trigger={<button />} />)
133+
wrapper.find('button').simulate('click')
133134

134135
onOpen.should.have.been.calledOnce()
135136
onOpen.should.have.been.calledWithMatch(null, { portalOpen: true })
136137
})
137138

138139
it('changes `portalOpen` to true', () => {
139-
const trigger = <button />
140-
wrapperMount(<TransitionablePortal {...requiredProps} trigger={trigger} />)
140+
wrapperMount(<TransitionablePortal {...requiredProps} trigger={<button />} />)
141141

142142
wrapper.find('button').simulate('click')
143143
wrapper.should.have.state('portalOpen', true)
@@ -148,6 +148,7 @@ describe('TransitionablePortal', () => {
148148
it('does not block update of state on Portal close', () => {
149149
wrapperMount(<TransitionablePortal {...requiredProps} open />)
150150
wrapper.should.have.state('portalOpen', true)
151+
wrapper.update()
151152

152153
domEvent.click(document.body)
153154
wrapper.should.have.state('portalOpen', false)

0 commit comments

Comments
 (0)