ademilter / ademilter/bricklayer

React.js errors when updating a component which has Bricklayer content in it

Aberta
#23 1 comentário 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
TypeScript
Estrelas
2.4k
Forks
116
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

I am unable to make React work with Bricklayer reliably. Problem happens when you mount a component which has Bricklayer content in it and update the component w/o unmounting.
## Repro Steps

```
git clone git@github.com:tugberkugurlu/ReactJsSamples.git
cd ReactJsSamples/BricklayerRepro
git checkout -qf f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9
yarn
npm start
```

Open the app on `http://localhost:3000` and fire up Chrome Dev Tools as well to see the errors. The app initially loads random items and bricklayer nicely shapes them ([see `componentDidMount`](https://github.com/tugberkugurlu/ReactJsSamples/blob/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro/src/index.js#L11-L13)). However, [`HomePage` component](https://github.com/tugberkugurlu/ReactJsSamples/blob/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro/src/index.js#L53-L74) updates the content of [`ItemsList` component](https://github.com/tugberkugurlu/ReactJsSamples/blob/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro/src/index.js#L10-L32) without unmounting it [in every 3 seconds](https://github.com/tugberkugurlu/ReactJsSamples/blob/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro/src/index.js#L60-L64). That's why I have the `destroy` and reinitialize code [inside `componentDidUpdate`](https://github.com/tugberkugurlu/ReactJsSamples/blob/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro/src/index.js#L14-L17).

However, any update that `ItemsList` receives makes react upset and it fails even before getting to `componentDidUpdate` and it's not able to remove any elements from the DOM and it builds up indefinitely like that.

The first error is the below one:

> DOMChildrenOperations.js:67 Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.removeChild @ DOMChildrenOperations.js:67processUpdates @ DOMChildrenOperations.js:183dangerouslyProcessChildrenUpdates @ ReactDOMIDOperations.js:30processQueue @ ReactMultiChild.js:139_updateChildren @ ReactMultiChild.js:359updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670receiveComponent @ ReactCompositeComponent.js:564receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670performUpdateIfNecessary @ ReactCompositeComponent.js:578performUpdateIfNecessary @ ReactReconciler.js:163runBatchedUpdates @ ReactUpdates.js:151perform @ Transaction.js:138perform @ Transaction.js:138perform @ ReactUpdates.js:90flushBatchedUpdates @ ReactUpdates.js:173closeAll @ Transaction.js:204perform @ Transaction.js:151batchedUpdates @ ReactDefaultBatchingStrategy.js:63enqueueUpdate @ ReactUpdates.js:201enqueueUpdate @ ReactUpdateQueue.js:25enqueueSetState @ ReactUpdateQueue.js:210ReactComponent.setState @ ReactComponent.js:64(anonymous function) @ index.js:103
> 16DOMChildrenOperations.js:67 Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.removeChild @ DOMChildrenOperations.js:67processUpdates @ DOMChildrenOperations.js:183dangerouslyProcessChildrenUpdates @ ReactDOMIDOperations.js:30processQueue @ ReactMultiChild.js:139_updateChildren @ ReactMultiChild.js:359updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670receiveComponent @ ReactCompositeComponent.js:564receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670performUpdateIfNecessary @ ReactCompositeComponent.js:578performUpdateIfNecessary @ ReactReconciler.js:163runBatchedUpdates @ ReactUpdates.js:151perform @ Transaction.js:138perform @ Transaction.js:138perform @ ReactUpdates.js:90flushBatchedUpdates @ ReactUpdates.js:173closeAll @ Transaction.js:204perform @ Transaction.js:151batchedUpdates @ ReactDefaultBatchingStrategy.js:63enqueueUpdate @ ReactUpdates.js:201enqueueUpdate @ ReactUpdateQueue.js:25enqueueSetState @ ReactUpdateQueue.js:210ReactComponent.setState @ ReactComponent.js:64(anonymous function) @ index.js:103

After that, subsequent errors are the same as below one for each update that happens every 3 seconds:

> DOMChildrenOperations.js:67 Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.removeChild @ DOMChildrenOperations.js:67processUpdates @ DOMChildrenOperations.js:183dangerouslyProcessChildrenUpdates @ ReactDOMIDOperations.js:30processQueue @ ReactMultiChild.js:139_updateChildren @ ReactMultiChild.js:359updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670receiveComponent @ ReactCompositeComponent.js:564receiveComponent @ ReactReconciler.js:129updateChildren @ ReactChildReconciler.js:107_reconcilerUpdateChildren @ ReactMultiChild.js:213_updateChildren @ ReactMultiChild.js:316updateChildren @ ReactMultiChild.js:303_updateDOMChildren @ ReactDOMComponent.js:960updateComponent @ ReactDOMComponent.js:780receiveComponent @ ReactDOMComponent.js:734receiveComponent @ ReactReconciler.js:129_updateRenderedComponent @ ReactCompositeComponent.js:784_performComponentUpdate @ ReactCompositeComponent.js:753updateComponent @ ReactCompositeComponent.js:670performUpdateIfNecessary @ ReactCompositeComponent.js:578performUpdateIfNecessary @ ReactReconciler.js:163runBatchedUpdates @ ReactUpdates.js:151perform @ Transaction.js:138perform @ Transaction.js:138perform @ ReactUpdates.js:90flushBatchedUpdates @ ReactUpdates.js:173closeAll @ Transaction.js:204perform @ Transaction.js:151batchedUpdates @ ReactDefaultBatchingStrategy.js:63enqueueUpdate @ ReactUpdates.js:201enqueueUpdate @ ReactUpdateQueue.js:25enqueueSetState @ ReactUpdateQueue.js:210ReactComponent.setState @ ReactComponent.js:64(anonymous function) @ index.js:103

This is what I see in this repro example. However, in my actual application, I am observing the below error on the same issue which is a bit different:

```
VM26259:1 Uncaught TypeError: error.stack is not a function
at eval (eval at evaluate (unknown source), :1:7)
at eval (webpack:///./src/components/common/formUtils.js?:17:13)(anonymous function) @ VM26259:1(anonymous function) @ formUtils.js:17
error
TypeError: Cannot read property 'getHostNode' of null
at Object.getHostNode (webpack:///./~/react/lib/ReactReconciler.js?:64:28)
at ReactCompositeComponentWrapper.getHostNode (webpack:///./~/react/lib/ReactCompositeComponent.js?:383:28)
at Object.getHostNode (webpack:///./~/react/lib/ReactReconciler.js?:64:29)
at Object.updateChildren (webpack:///./~/react/lib/ReactChildReconciler.js?:130:46)
at ReactDOMComponent._reconcilerUpdateChildren (webpack:///./~/react/lib/ReactMultiChild.js?:210:32)
at ReactDOMComponent._updateChildren (webpack:///./~/react/lib/ReactMultiChild.js?:314:31)
at ReactDOMComponent.updateChildren (webpack:///./~/react/lib/ReactMultiChild.js?:301:12)
at ReactDOMComponent._updateDOMChildren (webpack:///./~/react/lib/ReactDOMComponent.js?:942:12)
at ReactDOMComponent.updateComponent (webpack:///./~/react/lib/ReactDOMComponent.js?:760:10)
at ReactDOMComponent.receiveComponent (webpack:///./~/react/lib/ReactDOMComponent.js?:718:10)
```
## Sample Code

Adding the code used for repro steps here just for reference. However, it has dependencies as you can see. So, it will not work as is. Look at [here](https://github.com/tugberkugurlu/ReactJsSamples/tree/f8cf2f2d958e597cb9aa3129c7d5c2f045f7f3f9/BricklayerRepro) to make it work with the above repro steps.

``` jsx
import './bootswatch.less';
import 'bricklayer/dist/bricklayer.css';
import './index.scss';
import React from 'react';
import ReactDom from 'react-dom';
import Bricklayer from 'bricklayer';
import loremIpsum from 'lorem-ipsum';
import _ from 'underscore';

const ItemsList = React.createClass({
componentDidMount: function() {
this.itemsListContainerBricklayer = new Bricklayer(this.refs.itemsListContainer);
},
componentDidUpdate: function() {
this.itemsListContainerBricklayer.destroy();
this.itemsListContainerBricklayer = new Bricklayer(this.refs.itemsListContainer);
},
render: function() {
const { items } = this.props;
return





{items.map(item =>
{item.content}

)}



;
}
});

export const guid = () => {
const s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};

return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
};

const getRandomItems = () => {
const count = _.random(20, 100);
return _(_.range(count)).map(i => ({
id: guid(),
content: loremIpsum()
}));
};

const HelloWorld = React.createClass({
getInitialState: function() {
return {
items: getRandomItems()
};
},
componentDidMount: function() {
this.timerId = window.setInterval(() => {
this.setState({
items: getRandomItems()
});
}, 3000);
},
componentWillUnmount: function() {
window.clearInterval(this.timerId);
},
render: function() {
return



;
}
});

ReactDom.render(
,
document.getElementById('app')
);
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.