React.jsの薄い場所

Reactは、もちろん、複雑なインターフェイスの作成を簡素化する画期的なテクノロジーですが、抽象化と同様に、独自の小さな問題と機能があります。 私の練習では、あまり明白ではない4つに出会いました。 それをバグと呼ぶのは難しいです-それは単にライブラリの機能です。 今日はそれらについてお話します。









最初の瞬間-0.14でアルゴリズムが変更され、ルート要素を再描画するかどうかを決定しました



このような微妙な点がありますが、ドキュメントには記載されていません。 バージョン0.14より前では、 React.render()



呼び出しは常に、渡されたものを再描画しました。 ルート要素へのリンクを保存できます...



 const element = <MyComponent />;
      
      





...そしてReact.render(element)



呼び出すたびにアプリケーションが再描画されます。



0.14では、 props



改善され、アルゴリズムは「よりスマート」になりました。 現在、同じオブジェクトが到着すると、 props



state



すでに描画されてstate



ことを確認します。 つまり、要素へのリンクを保存したら、そのstate



変更するか、コピーを作成するか、レンダリングの前にsetProps()



実行する必要があります。



 import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { render() { const date = Date.now(); return <div>The time is {date}</div>; } } const app = document.getElementById("app"); const element = <MyComponent />; const ref = ReactDOM.render(element, app); ReactDOM.render(element, app); //    render() ref.forceUpdate(); //  
      
      





別の方法は、常に新しい要素を作成することです:



 const app = document.getElementById("app"); const ref = ReactDOM.render(<MyComponent />, app); ReactDOM.render(<MyComponent />, app);
      
      







2番目の瞬間-コントロールを使用している場合、ReactDOM.render()の呼び出しは、コントロールのイベントと同期して実行する必要があります



, . ., ReactDOM.render() .



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !




















を使用, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















 ,  . .,             ReactDOM.render()
      
      



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















 ,  . .,             ReactDOM.render()
      
      



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















 ,  . .,             ReactDOM.render()
      
      



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















 ,  . .,             ReactDOM.render()
      
      



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















 ,  . .,             ReactDOM.render()
      
      



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !
















, . ., ReactDOM.render()



.



, , , - - .



import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { bizLogic1(e.currentTarget.value); bizLogic2(e.currentTarget.value); bizLogic3(e.currentTarget.value); } render() { return ( <select size="3" value={this.props.selectedId} onChange={this.handleChange.bind(this)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> ); } }






... FLUX- , , , selectedId



, - bizLogic1-3



, . , bizLogic*



, , , .



let selectedId = 1; const app = document.getElementById("app"); function bizLogic1(newValue) { selectedId = newValue; renderAfterwards(); } function bizLogic2(newValue) { //... renderAfterwards(); } function bizLogic3(newValue) { //... renderAfterwards(); } let renderRequested = false; function renderAfterwards() { if (!renderRequested) { // , , // render() <select> window.setTimeout(() => { ReactDOM.render(<MyComponent selectedId={selectedId} />, app, () => { renderRequested = false; }); }, 0); } } //initial render ReactDOM.render(<MyComponent selectedId={selectedId} />, app);





, , select' — , 'onchange'



, bizLogic1-3



, props



. , . React ( ) <select'>



. ReactDOM.render()



, , , , .



, UI ReactDOM.render()



.



Dispatcher FLUX:



class MyComponent extends React.Component { handleChange(e) { dispatch({action: "ACTION_OPTION_SELECT", value: e.currentTarget.value}); } ... } function dispatch(action) { if (action.action === "ACTION_OPTION_SELECT") { bizLogic1(action); bizLogic2(action); bizLogic3(action); } ReactDOM.render(<MyComponent selectedId={selectedId} />, app); }







TestUtils.Simulate.change







, , React TestUtils , , . , ReactUtils , . , target



currentTarget



:



describe("MyInput", function() { it("refuses to accept DEF", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); var fakeInput = {value: "DEF"}; TestUtils.Simulate.change(rootNode, {currentTarget: fakeInput}); // , TestUtils currentTarget expect($(rootNode).val()).toEqual("abc"); // , .. handleChange <input> currentTarget }); });





( , ) ,



2 — React , . - , , .



:



import {$} from "commonjs-zepto"; import React from "react"; import ReactDOM from "react-dom"; class MyComponent extends React.Component { handleChange(e) { let value = e.currentTarget.value; if (!value.match(/[0-9]/)) bizLogic(value); } render() { return <input type="text" value={this.props.value} onChange={this.handleChange.bind(this)} />; } } const app = document.getElementById("app"); describe("MyInput", function() { it("refuses to accept digits", function() { var ref = ReactDOM.render(<MyComponent value="abc" />, app); var rootNode = ReactDOM.findDOMNode(ref); $(rootNode).val("abc1"); // TestUtils.Simulate.change(rootNode); //handleChange <input value="abc1"> // React "abc" expect($(rootNode).val()).toEqual("abc"); // , , .. value React' // , bizLogic , , "abc" }); });





, , !



















All Articles