手动修改DOM的innerHTML会停止ReactJS监听器
Manual innerHTML modification on DOM halts ReactJS listeners
我正在学习ReactJS和Node/Express生态系统(对我来说是早期的)。我有一个基本的ReactJS文件,包括组件定义和呈现调用。它能像预期的那样独立工作。为了快速/简单地调试,昨天我对客户端代码做了以下更改:
// Added HTML id to body tag, no other changes whatsoever to DOM/HTML
<body id='body'>...</body>
// In client code, added:
document.getElementById('body').innerHTML += xhr.responseText;
xhr
是一个有效的xmlHttpRequest()。我发出请求,得到响应,然后按照预期呈现给主体。然而,这个会阻止所有的ReactJS组件监听它们的按钮并按照定义触发它们的处理程序。没有控制台反馈或其他任何错误的迹象,ReactJS只是按预期进行第一次渲染,然后默默地停止响应。
如果我注释掉单行document.getEle...
,然后一切又开始工作,包括React和xhr
本身。
我知道在ReactJS的范式是不修改DOM以这种方式,但我不明白为什么这一行会破坏所有的ReactJS功能。对于上下文,这里是我的代码的一部分:
无论是否使用document.getEle…注释掉。
// Hello World component: manage cookies and display a simple prop
var HelloWorldComponent = React.createClass({
componentWillMount: function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if( xhr.readyState == 4 && xhr.status == 200 ) {
// NOTE: this `console.log` gives expected result regardless
console.log('Performed initial cookie check. Got response: ' + xhr.responseText);
// document.getElementById('body').innerHTML += '<div>'+xhr.responseText+'</div>';
}
else {
console.log('Tried initial cookie check. Got HTTP response status: ' + xhr.status);
}
}
xhr.open('POST', '/cookieCheck');
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.send();
},
render: function() {
return (
<h1 id='italic-id' className='red-class'>Hello, {this.props.name}!</h1>
);
}
});
该组件中断,除非 这是我如何渲染我的组件: 为了它的价值,我已经尝试了document.getEle...
被注释掉,否则它可以完美地工作。// State component to display simple state
var StateComponent = React.createClass({
// ReactJS Event: this fails with `document.getEle...` appearing elsewhere in the code
incrementCount: function() {
this.setState({
count: this.state.count + 1
});
},
getInitialState: function() {
return {
count: 0
}
},
render: function() {
return (
<div className='increment-component'>
<h3 className='red-class'>Count: {this.state.count}.</h3>
<button onClick={this.incrementCount}>Boing!</button>
</div>
);
}
});
ReactDOM.render(
<StateComponent/>,
document.getElementById('state-point')
);
// similar calls for other components as needed
document.getEle...
作为第一个JS触发,作为最后一个JS触发,正如你现在看到的,它是一个ReactJS组件的一部分。无论我把它放在代码的哪个位置,结果都是一样的。
我认为原因是由于innerHTML
的工作方式。它完全重新解析并替换了子DOM节点(即使您使用+=只是附加新节点),因此它破坏了先前附加到这些DOM节点的所有事件处理程序,在您的情况下是由React"管理"的DOM子树。对于您的情况,您可能需要考虑使用insertAdjacentHTML
。
来自MDN文档(https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML):
)"它不会重新解析正在使用它的元素,因此它不会破坏元素内的现有元素。"
尝试如下:
document.getElementById('body').insertAdjacentHTML('beforeend', xhr.responseText);
- 如何在ReactJS JSX中执行嵌套的if-else语句
- 拨打'父亲'函数形式a'儿童'ReactJS中的组件
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 如何更改reactjs中外部/独立组件的状态或属性
- Javascript全局onclick监听器
- ReactJS和SpringDataRest缓存问题可能与websocket有关
- 如何在td元素中添加监听器
- reactjs this.refs vs document.getElementById
- 同构reactjs-cdn资产
- 监听器必须是一个函数
- 在ReactJS中重新渲染孩子3次可以接受吗
- 如何在ReactJs中显示Json数据
- 将IndexedDB中的数据拉入数组,并通过ReactJS输出
- 如何在ReactJs中渲染子组件时重新加载子组件的数据
- 如何在ReactJs中链接下拉列表和文本区域
- 如何在ReactJs中呈现选定选项的更改表
- 在select上呈现不同形式的reactjs
- onClick事件未触发reactjs
- 如何在ReactJs中渲染重音符号
- 手动修改DOM的innerHTML会停止ReactJS监听器