2016-10-10 68 views
0

我正在學習ReactJS和Node/Express生態系統(對我而言是早期)。我有一個基本的ReactJS文件,包括組件定義和渲染調用。它可以按預期自行工作。爲了快速/調試方便起見,昨天我做的客戶端代碼以下變化:()在DOM暫停手動修改innerHTML 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組件的一部分。無論我把它放在代碼中,結果都是一樣的。

回答

1

我認爲原因是由於innerHTML的工作原理。它完全重新解析和替換子節點DOM節點(即使你正在使用+ =來添加新節點),所以它會銷燬所有先前連接到這些DOM節點的事件處理程序,在這種情況下,DOM子樹「被管理「通過React。 對於您的情況,您可能需要考慮使用insertAdjacentHTML來代替。

從MDN文檔(https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML):

「它不重新分析它被所使用的元件,因此它不會損壞元件內部的現有元素」。

具有以下嘗試:

document.getElementById('body').insertAdjacentHTML('beforeend', xhr.responseText);