Skip to content

Commit 2e43996

Browse files
committed
Adds support for UNSAFE_componentWillMount and getDerivedStateFromProps.
1 parent 3c8890e commit 2e43996

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

src/__tests__/index.test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,60 @@ describe('reactTreeWalker', () => {
157157
)
158158
})
159159

160+
it('UNSAFE_componentWillMount', () => {
161+
let actual = {}
162+
163+
class Foo extends Component {
164+
constructor(props) {
165+
super(props)
166+
this.state = { foo: 'foo' }
167+
}
168+
169+
UNSAFE_componentWillMount() {
170+
this.setState({ foo: 'bar' })
171+
}
172+
173+
render() {
174+
actual = this.state
175+
return h('div', null, this.state.foo)
176+
}
177+
}
178+
179+
return reactTreeWalker(h(Foo, { value: 'foo' }), () => true).then(
180+
() => {
181+
const expected = { foo: 'bar' }
182+
expect(actual).toMatchObject(expected)
183+
},
184+
)
185+
})
186+
187+
it('getDerivedStateFromProps', () => {
188+
let actual = {}
189+
190+
class Foo extends Component {
191+
constructor(props) {
192+
super(props)
193+
this.state = { foo: 'foo' }
194+
}
195+
196+
static getDerivedStateFromProps(props, state) {
197+
return { foo: `${state.foo}bar` }
198+
}
199+
200+
render() {
201+
actual = this.state
202+
return h('div', null, this.state.foo)
203+
}
204+
}
205+
206+
return reactTreeWalker(h(Foo, { value: 'foo' }), () => true).then(
207+
() => {
208+
const expected = { foo: 'foobar' }
209+
expect(actual).toMatchObject(expected)
210+
},
211+
)
212+
})
213+
160214
it('calls componentWillUnmount', () => {
161215
let called = true
162216

src/index.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ const ensureChild = child =>
5656
const getChildren = element =>
5757
element.props && element.props.children
5858
? element.props.children
59-
: element.children ? element.children : undefined
59+
: element.children
60+
? element.children
61+
: undefined
6062

6163
// Preact uses "nodeName", React uses "type"
6264
const getType = element => element.type || element.nodeName
@@ -192,7 +194,9 @@ export default function reactTreeWalker(
192194
const instance = new Component(props, currentContext)
193195

194196
// In case the user doesn't pass these to super in the constructor
195-
instance.props = instance.props || props
197+
Object.defineProperty(instance, 'props', {
198+
value: instance.props || props,
199+
})
196200
instance.context = instance.context || currentContext
197201
// set the instance state to null (not undefined) if not set, to match React behaviour
198202
instance.state = instance.state || null
@@ -210,7 +214,17 @@ export default function reactTreeWalker(
210214
instance.state = Object.assign({}, instance.state, newState)
211215
}
212216

213-
if (instance.componentWillMount) {
217+
if (Component.getDerivedStateFromProps) {
218+
const result = Component.getDerivedStateFromProps(
219+
instance.props,
220+
instance.state,
221+
)
222+
if (result !== null) {
223+
instance.state = Object.assign({}, instance.state, result)
224+
}
225+
} else if (instance.UNSAFE_componentWillMount) {
226+
instance.UNSAFE_componentWillMount()
227+
} else if (instance.componentWillMount) {
214228
instance.componentWillMount()
215229
}
216230

0 commit comments

Comments
 (0)