2016-10-10 6 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が検証、機能のX​​MLHttpRequestです():迅速/容易なデバッグの目的のために、昨日は私がクライアントコードで次の変更を行いました。私はリクエストを行い、応答を得て、期待通りにボディにレンダリングします。ただし、は、すべてのReactJSコンポーネントがボタンをリッスンして定義されているようにハンドラを起動しないように、を停止します。コンソールのフィードバックや何か間違ったサインがないので、ReactJSは最初に期待通りにレンダリングした後、静かに応答を停止します。

私が単一の行をコメントアウトすると、Reactとxhrを含め、すべてが再び動作し始めます。

ReactJSでは、このようにDOMを変更するのはパラダイムではありませんが、なぜこの1行で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 

最初のJSが最後のJSが解雇として、解雇、そしてあなたのように、私はdocument.getEle...を試してみましたこれをReactJSコンポーネントの一部として参照してください。結果はコードにどこに置いても同じです。

答えて

1

理由は、innerHTMLがどのように機能するかによると考えています。それは子供のDOMノードを完全に再解析して置き換えます(たとえ+ =を使って新しいノードを追加しても)。そのためDOMノードに以前に付けられたすべてのイベントハンドラが破棄されます。 "React。 あなたの場合、insertAdjacentHTMLを代わりに使用することを検討する必要があります。 MDNドキュメント(https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML)から

「それはそれはで使用されている要素を再解析しませんので、それは要素内の既存の要素壊れない」

次で試してみてください:

document.getElementById('body').insertAdjacentHTML('beforeend', xhr.responseText); 
関連する問題