2015-10-01 8 views
7

私はリアクションで何かしようとしていますが、これは他のフレームワークでは非常に簡単です:フォームから値の束を集めたいと思います。ベストプラクティスでフォームデータを読むために

は、以前私がバックボーンビューこの種のものをやって、それは非常に簡単だった:

readFormValues: function() { 
    this.data.foo = this.$('[name="foo"]').val(); 
    this.data.bar = this.$('[name="bar"]:checked').val(); 
}); 

しかし、中には、私はそれを行うための簡単な方法を見つけることができないよう反応します。 ...私の唯一のオプションは、にしているようだ

注:フォーマット用謝罪:コードブロックとリストが完全にバイパスが反応し、jQueryの使用

  1. :-(一緒にうまく再生されません

    handleSubmit: function(e) {

    var $form = $(e.target).parents('form:first');

    :フォームにアクセスするには、+

    this.data.foo = $form.find('[name="foo"]);

    },

    render: function() {

    return <form onSubmit="handleSubmit"><input name="foo"/></form>;動作し、シンプルですが、それは私が反応バイパスとjQueryを使用していますように感じている

    }

    とき、私はちょうどべきリアクションを使用している。

  2. すべてのフォームコントロールにコールバックを提供します

    handleFooClick: function(e) {

    this.data.foo = event.target.value;

    },

    render: function() {

    return <form><input name="foo" onChange="handleFooChange"/></form>;

    }

    これはリアクト/フラックスのようですが、不必要な作業が狂っているように感じます。私のバックボーンの例では、フォームコントロールごとに1行だけ必要でしたが、このアプローチでは、最後のすべてのコントロールは独自のonChangeハンドラを持っていなければなりません。

    EDIT:このアプローチの1つの以上の欠点は、コールバックthis.propsthis.state内の私のフォームコントロールの小道具/状態を指していないということ(それは入力の小道具/状態を指します)です。つまり、入力ごとにハンドラを作成し、レンダリングするときにそのコールバックをすべての入力に追加するだけでなく、データオブジェクトをすべての入力に渡す必要があります。

  3. 使用、参考文献:

    handleSubmit: function(e) {

    this.state.data.foo = this.refs.foo.value;

    },

    render: function() {

    return <form><input ref="foo"/></form>;

    }

    これは、すべてのフォームコントロールに「ref」属性を追加するだけで、バックボーンで簡単にデータを読み取ることができます。しかし、すべてのReactのドキュメンテーションには、refを使った方法が間違っていることが示唆されています(refを使用するすべての例では、コントロールにデータを読み込むのではなく、 "この入力に焦点を当てる"など)。

は私が不複雑ではない、私のフォームデータにアクセスするための「-IVEに反応」の方法がなければならないように感じるが、私は十分に反応理解していないので、私はそれを見ていませんよ。私が見逃していることをリアクトエキスパートが説明できるなら、私はそれを高く評価します。

答えて

2

まず、jQueryの不要な依存関係であり、それはそうのは、それを排除せてクリーンなオプションではありません。

次に、柔軟性に問題があります。詳細はanswerを参照してください。最も単純な場合を除いて、すべての点について基準を定めましょう。

これは、Facebookがと呼ぶオプション#2を残します。コントロールされたコンポーネントは、すべてのユースケース(キーアップ時の検証など)をカバーするため、優れています。あまりコードはありませんが、フォーム要素ごとに単純な変更ハンドラを追加するのではなく、bindを使用するすべての要素に対して1つの変更ハンドラを使用できます。このようなもの:

handleChange: function(fieldName, e) { 
    console.log("field name", fieldName); 
    console.log("field value", e.target.value); 
    // Set state or use external state. 
}, 

render: function() { 
    var someValue = this.state.someValue; // Or a prop is using external state 
    return (
    <div> 
     <input 
     name="someName" 
     value={someValue} 
     onChange={this.handleChange.bind(this, "someName")} /> 
    </div> 
) 
} 

さらに詳しくは、answerを参照してください。私は戻って、すべての入力のための単一のonChangeコール使用されている小さなプロジェクトのために

1

ReactLinkを使用すると、反応コンポーネントと状態の間に双方向バインディングを作成できます。ここで説明

https://facebook.github.io/react/docs/two-way-binding-helpers.html

+0

を拡張します。私は「リアクトリンク」が存在することに気づいていなかった。しかし、私はそれについて2つのことを見る。第一に、あなたがリンクした記事は、「フレームワークが初めての場合、ReactLinkはほとんどのアプリケーションでは必要ではないので、慎重に使用する必要があります。第二に、ミックスインが必要だと思われ、ミックスインはReactで廃止されたと考えましたか? – machineghost

1

- このような何かを...

HandleClick(event) { 
    let values = this.state.values; 
    values[event.target.name] = event.target.value; 
    this.setState({values}); 
} 

これは、あなたがそれらの状態のプロパティに名前を付けると、あなたが同じことを、あなたの入力に名前を付けることが必要ですが、私はそれが大好きです。次に、stateに格納された値を入力のvalue属性に渡すと、すべてのフォーム状態が1つのハンドラ関数で1か所に格納されます。

もちろん、よりスケーラブルな方法があります。私は面白いと思われるフォームと呼ばれる反応のフレームワークについて読んでいました。 http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html

希望これは、私は、フォーム内のすべてのフィールドを処理する方法である

ダン

1

を支援します。ここではチュートリアルです。

  var My_Field=React.createClass({ 
       _onChange: function(evt) { 
        var e=this.props.parent_form; 
        if (e) { 
         e.setState({email: evt.target.value}); 
        } 
       }, 
       render: function() { 
        return (
         <input type="text" name={this.props.name} placeholder={this.props.label} onChange={this._onChange}/> 
        ); 
       } 
      }); 

      var My_Form=React.createClass({ 
       getInitialState: function() { 
        return { 
         email: "", 
        }; 
       }, 
       _onSubmit: function(evt) { 
        evt.preventDefault(); 
        alert(this.state.email); 
       }, 
       render: function() { 
        return (
         <form onSubmit={this._onSubmit}> 
          <My_Field name="email" label="Email" parent_form={this}/> 
          <input type="submit" value="Submit"/> 
         </form> 
        ); 
       } 
      }); 
0

フォームデータは、1つの機能のみを使用して読み取ることができます。

クラスの申し込みが大きい提案のコンポーネント{

constructor(){ 
    super(); 
    this.handleLogin = this.handleLogin.bind(this); 
} 

handleLogin(e){ 
    e.preventDefault(); 
    const formData = {}; 
    for(const field in this.refs){ 
     formData[field] = this.refs[field].value; 
    } 
    console.log('-->', formData); 
} 
render(){ 
    return (
     <form onSubmit={this.handleLogin} className="form-horizontal"> 
        <div className="form-group text-left"> 
          <label className="control-label col-sm-2">Name:</label> 
          <div className="col-sm-10"> 
          <input ref="name" type="text" className="form-control" name="name" placeholder="Enter name" /> 
          </div> 
         </div> 
         <div className="form-group text-left"> 
          <label className="control-label col-sm-2">Email:</label> 
          <div className="col-sm-10"> 
          <input ref="email" type="email" className="form-control" name="email" placeholder="Enter email" /> 
          </div> 
         </div> 
         <div className="form-group text-left"> 
          <label className="control-label col-sm-2">Password:</label> 
          <div className="col-sm-10"> 
          <input ref="password" type="password" className="form-control" name="password" placeholder="Enter password" /> 
          </div> 
         </div> 
         <div className="form-group text-left"> 
          <div className="col-sm-offset-2 col-sm-10"> 
          <button type="submit" className="btn btn-primary btn-block">Signup</button> 
          </div> 
         </div> 
         </form> 
)   
} }export default SignUp; 
関連する問題