Skip to content

Commit 2de4e58

Browse files
theKasheygregberge
authored andcommitted
fix: proper children reconcile for nested tags, fixes #869 (#871)
React 15 issue.
1 parent 4b13ed1 commit 2de4e58

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

Diff for: src/reconciler/hotReplacementRender.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,19 @@ const mapChildren = (children, instances) => ({
129129
}
130130
}
131131

132-
const newChildren = asArray((child.props && child.props.children) || [])
132+
const newChildren = asArray(
133+
(child.props && child.props.children) || child.children || [],
134+
)
133135
const nextChildren =
134136
oldChildren.length && mapChildren(newChildren, oldChildren)
135137

136138
return {
137139
...instanceLine,
138-
// actually child merge is needed only for TAGs, and usually don't work for Components.
140+
// actually child merge is needed only for "HTML TAG"s, and usually don't work for Components.
139141
// the children from an instance or rendered children
140142
// while children from a props is just a props.
141143
// they could not exists. they could differ.
142-
...(nextChildren ? { children: nextChildren } : {}),
144+
...(nextChildren || {}),
143145
type: child.type,
144146
}
145147
}),

Diff for: test/reconciler.test.js

+40-2
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,50 @@ describe('reconciler', () => {
213213

214214
incrementGeneration()
215215
wrapper.setProps({ update: 'now' })
216-
expect(First.rendered).toHaveBeenCalledTimes(4)
216+
expect(First.rendered).toHaveBeenCalledTimes(3)
217+
expect(Second.rendered).toHaveBeenCalledTimes(3)
218+
219+
incrementGeneration()
220+
wrapper.setProps({ second: false })
221+
expect(First.rendered).toHaveBeenCalledTimes(5)
217222
expect(Second.rendered).toHaveBeenCalledTimes(4)
218223

224+
expect(First.unmounted).toHaveBeenCalledTimes(0)
225+
expect(Second.unmounted).toHaveBeenCalledTimes(1)
226+
})
227+
228+
it('should use new children branch during reconcile for full components', () => {
229+
const First = spyComponent(() => <u>1</u>, 'test', '1')
230+
const Second = spyComponent(() => <u>2</u>, 'test', '2')
231+
232+
const Section = ({ children }) => <div>{children}</div>
233+
234+
const App = ({ second }) => (
235+
<div>
236+
<div>
237+
<Section>
238+
<First.Component />
239+
{second && <Second.Component />}
240+
</Section>
241+
</div>
242+
</div>
243+
)
244+
245+
const Mounter = ({ second }) => <App second={second} />
246+
247+
const wrapper = mount(<Mounter second />)
248+
249+
expect(First.rendered).toHaveBeenCalledTimes(1)
250+
expect(Second.rendered).toHaveBeenCalledTimes(1)
251+
252+
incrementGeneration()
253+
wrapper.setProps({ update: 'now' })
254+
expect(First.rendered).toHaveBeenCalledTimes(3)
255+
expect(Second.rendered).toHaveBeenCalledTimes(3)
256+
219257
incrementGeneration()
220258
wrapper.setProps({ second: false })
221-
expect(First.rendered).toHaveBeenCalledTimes(7)
259+
expect(First.rendered).toHaveBeenCalledTimes(5)
222260
expect(Second.rendered).toHaveBeenCalledTimes(4)
223261

224262
expect(First.unmounted).toHaveBeenCalledTimes(0)

0 commit comments

Comments
 (0)