Reputation:
By clicking on the button in one component, I delete the component in the parent with such code:
// componentA.jsx
class ComponentA extends React.PureComponent {
removeB() {
this.setState({ mounted: false })
}
renderB() {
if (!this.state.mounted) {
return null
}
return <ComponentB />
}
render() {
return <div>
{this.renderB()}
<ComponentC onClick={this.removeB} />
</div>
}
}
// componentB.jsx
class ComponentB extends React.PureComponent {
render() {
return ...
}
}
// componentC.jsx
class ComponentC extends React.PureComponent {
render() {
return <Button onClick={this.props.onClick} />
}
}
I get the error:
Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
Upvotes: 1
Views: 149
Reputation: 2522
Your issue is because the this
variable inside function removeB
refers to the wrong scope (in your example the scope of ComponentC
, it should refer to the correct scope, which is ComponentA
).
You should correctly bind the event handler to the scope of ComponentA
before passing it.
You can do it in couple of ways:
class ComponentA extends React.PureComponent {
constructor() {
this.removeB = this.removeB.bind(this); // Bind event handlers in constructor
}
removeB() {
this.setState({ mounted: false })
}
....
render() {
return <div>
{this.renderB()}
<ComponentC onClick={this.removeB} />
</div>
}
}
Or:
class ComponentA extends React.PureComponent {
removeB = () => {
this.setState({ mounted: false })
} // Using arrow function to bind function to the current lexical scoping
....
render() {
return <div>
{this.renderB()}
<ComponentC onClick={this.removeB} />
</div>
}
}
You can read more about JS lexical scoping here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Also, React document mentioned about binding event handlers to the correct scope here:
https://reactjs.org/docs/handling-events.html
Upvotes: 1