2016-03-28 12 views
2

私はJames NelsonによってLearn React.js (without JSX)シリーズを使いました。このシリーズでは、Reactで実装されたフォームを紹介し、入力フィールドが効果的に読み取り専用であることを示してから、値を正しく変更する方法を説明します。これは、ではなく、です。むしろ、Reactがどのように値を変更できないかを理解したいと思います。Reactは入力フィールド値の変更をどのように抑えることができますか?

(またjsfiddleで)以下のコードはSSCCEある:単純なHTMLで作成した、ReactJS有する他:

<!doctype html> 
<html> 
    <head> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script> 
    </head> 
    <body> 
    <div> 
     <h3>simple HTML form (no ReactJS)</h3> 
     <form> 
     <input type='text' value placeholder='please enter your name'> 
     </form> 
    </div> 
    <div id='react-app'> 
     <script type='text/javascript'> 
     const rce = React.createElement.bind(React); 
     const rcc = React.createClass.bind(React); 

     const ContactForm = rcc({ 
     propTypes: { 
      value: React.PropTypes.object.isRequired, 
     }, 
     render: function() { 
      return rce('form', {} 
        , rce('input', {type: 'text' 
            , placeholder: 'please enter your name' 
            , value: this.props.value.name 
            , onInput: function(se) { 
            console.log(se.target.value); 
            }}))} 
     , componentWillMount  : function() {console.log('componentWillMount');} 
     , componentDidMount  : function() {console.log('componentDidMount');} 
     , componentWillReceiveProps: function() {console.log('componentWillReceiveProps');} 
     , shouldComponentUpdate : function() {console.log('shouldComponentUpdate');} 
     , componentWillUpdate  : function() {console.log('componentWillUpdate');}    
     , componentDidUpdate  : function() {console.log('componentDidUpdate');}    
     , componentWillUnmount  : function() {console.log('componentWillUnmount');} 
     }); 

     const ContactView = rcc({ 

     propTypes: { 
      newContact: React.PropTypes.object.isRequired, 
     } 
     ,render: function() { 
      console.log('render called'); 
      return rce('div', {} 
        , rce('h3', {}, 'why doesn\'t the input field value change?') 
       , rce(ContactForm, { 
       value: this.props.newContact 
       })) 
     } 
     }); 

     var reactApp = rce(ContactView, {newContact: {name: ''}}); 
     ReactDOM.render(reactApp, document.getElementById('react-app')); 
     </script> 
    </body> 
</html> 

上記コードは、2つのHTMLフォームを生成します。レンダリングされた要素は同じです:私はのためのコンソールにメッセージをログに記録しています

enter image description here

:ReactJSで作成したHTMLフォームの

enter image description here

:シンプルなHTMLフォームの

すべてのコンポーネントライフサイクルメソッドが呼び出されます。呼び出されるように見えるのは、render,componentWillMount、およびcomponentDidMountです(冒頭のみです)。入力テキストフィールドにキーストロークが入力された場合、その後のライフサイクルメソッドは呼び出されません。

だから私の質問は:追加のライフサイクルメソッドが呼び出されていないことを考えると、どのようにReactJSは、そのDOM表現は、プレーンなHTMLフォーム入力フィールドと同じであることを考えると変化するから、入力フィールドの値を防ぐために管理してい(私が入力フィールドに入力すると私のブラウザに表示される値はが実際に変更されますか?

答えて

4

リアクトはvirtual DOMという概念を使用します。それは "仮想的に"変化を追跡することであり、 "実際の" DOMをこの抽象的なものに置き換えます。

コンポーネントが(再)レンダリングされると、仮想DOMを「実際の」DOMにマップします。入力フィールドの値がpropsで受け取った値にバインドされても、変更されません(propsを変更していないため)。

入力した値と同期させて値を保持する場合は、コンポーネントstateに値をバインドすることができます。

あなたの2番目の質問については、私はまったくフォローしませんでしたが、component's lifecycleを見てみたいです。これにより、何らかの変更が発生したとき(たとえば、新しい小道具が渡されたとき)にコンポーネントを制御することができます。私ははっきりしていたとは思わないとして

更新

、私は少し手の込んだてみましょう。 docsによれば

<input type="text" name="title" value="Untitled" /> 

これは、値、Untitledを初期化入力をレンダリングします。ユーザーが入力を更新すると、ノードのvalueプロパティが変更されます。ただし、node.getAttribute('value')は、初期化時に使用される値、Untitledを返します。

[属性vs値は私を混乱させるかもしれません。 Here's an explanatory post.]

HTMLとは異なり、リアクションコンポーネントは、初期化時だけでなく、任意の時点でビューの状態を表す必要があります。例えば、中が反応:この方法は、任意の時点でのビューを記述する

render: function() { 
    return <input type="text" name="title" value="Untitled" />; 
} 

ので、テキスト入力の値は、常にUntitledであるべきです。

+0

私は仮想DOMについて理解していると思います。 ReactJSが入力フィールドの値を変更するのを防ぐにはどうすればいいのですか?(a)console.log( 'se.target.value')はキーストロークを報告します。値は少なくとも一時的に変更されました。(b)' render 'が各キーストロークの後に再び呼び出されることはないので、ReactJSには(一時的に変更された)' se.target.value'をオーバーライドし、 'props'を介してバウンド値にリセットする機会は与えられません。 –

+1

あなたは本当に入力しています、あなたが*値を割り当てているわけではありません。また、 '' '' state''や '' props''のいずれも変更しないので、 '' render'''はもう一度呼び出されません。 https://facebook.github.io/react/docs/forms.htmlの** Advanced Topics **をチェックしてください。また、*属性*と*値*の違いを理解するためにこの答えをチェックしてください:http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html –

+1

私は '属性'と '値の区別はありますが、使用するDOM要素が同一であることを前提とすると、ReactJSのケースではなく、プレーンなHTMLのケースでブラウザに変更が表示されるのはなぜですか? (できるだけ明確な点を作るために作成された2つの異なるDOMフォーム要素を示す質問を更新しました)。 ReactJSがシーンの背後にあるリスナーを接続して変更を上書きするのであれば、ReactJSがライブラリでありフレームワークではないという主張に対して飛びつくわけではありませんか? –

関連する問題