mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Prepare new composite child before removing old (#8572)
This matches what we do in Fiber -- and doing it this way is the only way we can prepare new views in the background before unmounting old ones.
In particular, this breaks this pattern:
```js
class Child1 extends React.Component {
render() { ... }
componentWillMount() {
this.props.registerChild(this);
}
componentWillUnmount() {
this.props.unregisterChild();
}
}
class Child2 extends React.Component {
render() { ... }
componentWillMount() {
this.props.registerChild(this);
}
componentWillUnmount() {
this.props.unregisterChild();
}
}
class Parent extends React.Component {
render() {
return (
showChild1 ?
<Child1
registerChild={(child) => this.registered = child}
unregisterChild={() => this.registered = null}
/> :
<Child2
registerChild={(child) => this.registered = child}
unregisterChild={() => this.registered = null}
/>
);
}
}
```
Previously, `this.registered` would always be set -- now, after a rerender, `this.registered` gets stuck at null because the old child's componentWillUnmount runs *after* the new child's componentWillMount.
A correct fix here is to use componentDidMount rather than componentWillMount. (In general, componentWillMount should not have side effects.) If Parent stored a list or set of registered children instead, there would also be no issue.
This commit is contained in:
@@ -1318,6 +1318,7 @@ src/renderers/shared/shared/__tests__/ReactCompositeComponent-test.js
|
||||
* should support objects with prototypes as state
|
||||
* should not warn about unmounting during unmounting
|
||||
* should only call componentWillUnmount once
|
||||
* prepares new child before unmounting old
|
||||
|
||||
src/renderers/shared/shared/__tests__/ReactCompositeComponentDOMMinimalism-test.js
|
||||
* should not render extra nodes for non-interpolated text
|
||||
@@ -1405,6 +1406,7 @@ src/renderers/shared/shared/__tests__/ReactMultiChild-test.js
|
||||
* should NOT replace children with different owners
|
||||
* should replace children with different keys
|
||||
* should reorder bailed-out children
|
||||
* prepares new children before unmounting old
|
||||
|
||||
src/renderers/shared/shared/__tests__/ReactMultiChildReconcile-test.js
|
||||
* should reset internal state if removed then readded in an array
|
||||
|
||||
Reference in New Issue
Block a user