React.js: एक ऑन चेंज हैंडलर के साथ विभिन्न इनपुट की पहचान करना


141

जिज्ञासु यह दृष्टिकोण करने का सही तरीका क्या है:

var Hello = React.createClass({
getInitialState: function() {
    return {total: 0, input1:0, input2:0};
},
render: function() {
    return (
        <div>{this.state.total}<br/>
            <input type="text" value={this.state.input1} onChange={this.handleChange} />
            <input type="text" value={this.state.input2} onChange={this.handleChange} />
        </div>
    );
},
handleChange: function(e){
    this.setState({ ??? : e.target.value});
    t = this.state.input1 + this.state.input2;
    this.setState({total: t});
}
});

React.renderComponent(<Hello />, document.getElementById('content'));

जाहिर है कि आप प्रत्येक अलग इनपुट को संभालने के लिए अलग-अलग हैंडलबार फ़ंक्शन बना सकते हैं, लेकिन यह बहुत अच्छा नहीं है। इसी तरह आप एक व्यक्तिगत इनपुट के लिए एक घटक बना सकते हैं, लेकिन मैं यह देखना चाहता था कि क्या ऐसा करने का कोई तरीका है।

जवाबों:


163

मैं मानक HTML विशेषताओं के लिए चिपके हुए सुझाव देते हैं जैसे nameपर inputतत्वों अपने आदानों की पहचान। इसके अलावा, आपको राज्य में "कुल" को एक अलग मूल्य के रूप में रखने की आवश्यकता नहीं है, क्योंकि यह आपके राज्य में अन्य मूल्यों को जोड़कर है।

var Hello = React.createClass({
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },
    render: function() {
        const total = this.state.input1 + this.state.input2;

        return (
            <div>{total}<br/>
                <input type="text" value={this.state.input1} name="input1" onChange={this.handleChange} />
                <input type="text" value={this.state.input2} name="input2" onChange={this.handleChange} />
            </div>
        );
    },
    handleChange: function(e) {
        this.setState({[e.target.name]: e.target.value});
    }
});

React.renderComponent(<Hello />, document.getElementById('content'));

3
मैं शुरू में ऐसा करने की कोशिश कर रहा था, लेकिन setState ({e.target.name ... काम नहीं करता है- यह एक सिंटैक्स त्रुटि है। आपको obj [e.target.name] के साथ एक अस्थायी ऑब्जेक्ट बनाना होगा और उस पर सेट करना होगा। इस तरह का काम करता है, लेकिन राज्य वस्तु अद्यतन में किसी प्रकार की देरी लगती है।
T3db0t

1
"देरी की तरह" अनुरोध के दौरान अद्यतन करने के लिए सेट किया गया है। कथनफ्रेम (मुझे लगता है), इसलिए उस टिप्पणी को अनदेखा करें
T3db0t

24
@ T3db0t यह ES6 वाक्य रचना काम करती है:this.setState({ [e.target.name]: e.target.value });
XåpplI'-I0llwlg'I -

2
बाइंड का उपयोग करना बेहतर तरीका है। यह दृष्टिकोण काम नहीं करता है यदि आप ऑनकॉन्ग हैंडलर को बिना किसी संपत्ति जैसे कि डिव के रूप में संलग्न करते हैं।
6

3
@ericgrosse बाइंड इस मामले में बेहतर नहीं है क्योंकि आप बहुत सारे अनावश्यक कार्य बना रहे हैं। इसके अलावा, आप एक डेटा का उपयोग कर सकते हैं
aw04

106

आप .bindविधि को पूर्व-निर्मित करने के लिए विधि का उपयोग कर सकते हैं handleChange। यह कुछ इस तरह होगा:

  var Hello = React.createClass({
    getInitialState: function() {
        return {input1:0, 
                input2:0};
    },
    render: function() {
      var total = this.state.input1 + this.state.input2;
      return (
        <div>{total}<br/>
          <input type="text" value={this.state.input1} 
                             onChange={this.handleChange.bind(this, 'input1')} />
          <input type="text" value={this.state.input2} 
                             onChange={this.handleChange.bind(this, 'input2')} />
        </div>
      );
    },
    handleChange: function (name, e) {
      var change = {};
      change[name] = e.target.value;
      this.setState(change);
    }
  });

  React.renderComponent(<Hello />, document.getElementById('content'));

(मुझे भी totalरेंडर समय पर गणना की जानी चाहिए, क्योंकि यह करने के लिए अनुशंसित चीज़ है।)


13
बस एक त्वरित अनुस्मारक जो this.handleChange.bind(...)एक नया फ़ंक्शन बनाता है। मामले में आप के shouldComponentUpdateसाथ उपयोग कर रहे हैं PureRenderMixinया कुछ इसी तरह यह टूट जाएगा। जब कोई एकल मान बदलता है, तो आपके सभी इनपुट घटक फिर से प्रस्तुत किए जाएंगे।
ज़मीर

5
आप के कार्यान्वयन को बदलते हैं handleChangeकरने के लिए handleChange(name) { return event => this.setState({name: event.target.value}); }आप "एक ही" समारोह पारित कर सकते हैं (नए कार्य के रूप में यह का उपयोग करके किया गया है नहीं बनाएगा .bind()तो, आप इस तरह के समारोह पारित कर सकते हैं:this.handleChange("input1")
Andreyco

1
मुझे लगता है कि यह उल्लेख करना भी महत्वपूर्ण है, कि setState की प्रकृति, यह है कि कोई भी वर्तमान स्थिति को हैंडचेंज फ़ंक्शन में पुनर्प्राप्त नहीं कर पाएगा, लेकिन पिछले राज्य का उपयोग करते हुए, यह .state.input1, उदाहरण के लिए। this.setState(change, function () { console.log(this.state.input1); );संदर्भ के रूप में कॉलबैक बनाने के लिए एक उचित दृष्टिकोण होगा : stackoverflow.com/questions/30782948/…
चार्ली-ग्रीनमैन

39

onChangeघटना बुलबुले ... आप इस तरह कुछ कर सकते हैं तो:

// A sample form
render () {
  <form onChange={setField}>
    <input name="input1" />
    <input name="input2" />
  </form>
}

और आपकी सेटफिल्ड विधि इस तरह दिख सकती है (मान लें कि आप ES2015 का उपयोग कर रहे हैं या बाद में:

setField (e) {
  this.setState({[e.target.name]: e.target.value})
}

मैं कई एप्स में ऐसा ही कुछ इस्तेमाल करता हूं, और यह काफी आसान है।


11

पदावनत समाधान

valueLink/checkedLinkकर रहे हैं पदावनत कोर से, प्रतिक्रिया, क्योंकि यह कुछ उपयोगकर्ताओं को भ्रमित कर रहा है। यदि आप प्रतिक्रिया के हाल के संस्करण का उपयोग करते हैं तो यह उत्तर काम नहीं करेगा। लेकिन अगर आप इसे पसंद करते हैं, तो आप आसानी से अपना खुद का Inputघटक बनाकर इसका अनुकरण कर सकते हैं

पुरानी उत्तर सामग्री:

रिएक्ट के 2-वे डेटा बाइंडिंग हेल्पर्स का उपयोग करके आप जो हासिल करना चाहते हैं, वह बहुत आसानी से हासिल किया जा सकता है।

var Hello = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },

    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
            <div>{total}<br/>
                <input type="text" valueLink={this.linkState('input1')} />;
                <input type="text" valueLink={this.linkState('input2')} />;
            </div>
        );
    }

});

React.renderComponent(<Hello />, document.getElementById('content'));

आसान है ना?

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

तुम भी अपने स्वयं के मिश्रण को लागू कर सकते हैं


हमें राज्य स्थापित करने के लिए एक onchange को क्यों बांधना होगा। यह ReactJS afterall है!
जुनैद कादिर

ध्यान दें कि इस समाधान को पदावनत किया गया है
फिलिप

6

आप इसे इस तरह भी कर सकते हैं:

...
constructor() {
    super();
    this.state = { input1: 0, input2: 0 };
    this.handleChange = this.handleChange.bind(this);
}

handleChange(input, value) {
    this.setState({
        [input]: value
    })
}

render() {
    const total = this.state.input1 + this.state.input2;
    return (
        <div>
            {total}<br />
            <input type="text" onChange={e => this.handleChange('input1', e.target.value)} />
            <input type="text" onChange={e => this.handleChange('input2', e.target.value)} />
        </div>
    )
}

मेरे लिए काम नहीं किया। देखा रिएक्टर डेवलपर उपकरण। इनपुट 1 / इनपुट 2 के बजाय वैरिएबल / ऑब्जेक्ट को इनपुट बनाने के लिए इसकी वैल्यू बनाना और असाइन करना
Gaurravs

1
@ गौरव आप सही हैं। मैं setState में []चारों ओर जोड़ने की जरूरत है input। वह संपत्ति को गतिशील बनाता है
इनोस्टिया

4

आप एक विशेष उपयोग कर सकते हैं Reactविशेषता बुलाया refऔर फिर असली डोम नोड्स से मेल onChangeका उपयोग कर घटना Reactके getDOMNode()समारोह:

handleClick: function(event) {
  if (event.target === this.refs.prev.getDOMNode()) {
    ...
  }
}

render: function() {
  ...
  <button ref="prev" onClick={this.handleClick}>Previous question</button>
  <button ref="next" onClick={this.handleClick}>Next question</button>
  ...
}

कम से कम 0.13 में this.refs के पास प्रॉपर्टी प्रीफ़ नहीं है।
blub

2
@usagidon - prevसिर्फ एक नाम है जिसे मैंने render()विधि में सेट किया है
Janusz Kacalak

2
प्रतिक्रिया v0.14 के अनुसार, आप बस कर सकते हैं event.target === this.refs.prevfacebook.github.io/react/blog/2015/10/07/…
XåpplI'-I0llwlg'I -

0

@ विगिल डिसग्रेस 4

जब यह बहु क्षेत्र रूपों की बात आती है, तो यह रिएक्ट की प्रमुख विशेषता का उपयोग करने के लिए समझ में आता है: घटक।

मेरी परियोजनाओं में, मैं TextField घटक बनाता हूं, जो न्यूनतम मूल्य मान लेता है, और यह एक इनपुट पाठ क्षेत्र के सामान्य व्यवहार को संभालने का ख्याल रखता है। इस तरह आपको मूल्य स्थिति को अपडेट करते समय फ़ील्ड नामों पर नज़र रखने के बारे में चिंता करने की ज़रूरत नहीं है।

[...]

handleChange: function(event) {
  this.setState({value: event.target.value});
},
render: function() {
  var value = this.state.value;
  return <input type="text" value={value} onChange={this.handleChange} />;
}

[...]

0

आप inputएक अलग InputFieldघटक बनाकर प्रत्येक बच्चे के मूल्य को ट्रैक कर सकते हैं जो एकल के मूल्य का प्रबंधन करता है input। उदाहरण के लिए InputFieldहो सकता है:

var InputField = React.createClass({
  getInitialState: function () {
    return({text: this.props.text})
  },
  onChangeHandler: function (event) {
     this.setState({text: event.target.value})
  }, 
  render: function () {
    return (<input onChange={this.onChangeHandler} value={this.state.text} />)
  }
})

अब प्रत्येक बच्चे के घटक की निगरानी के लिए माता-पिता की स्थिति में अलग-अलग मान बनाए बिना inputइस InputFieldघटक के एक अलग उदाहरण के भीतर प्रत्येक के मूल्य को ट्रैक किया जा सकता है ।


0

मैं वास्तव में समस्या का सरल समाधान प्रदान करूंगा। मान लीजिए हमारे पास दो इनपुट हैं usernameऔरpassword , लेकिन हम चाहते हैं कि हमारा हैंडल आसान और सामान्य हो, इसलिए हम इसका पुन: उपयोग कर सकते हैं और boleplate कोड नहीं लिख सकते।

I.Our फार्म:

                <form>
                    <input type="text" name = "username" onChange={this.onChange} value={this.state.username}/>
                    <input type="text" name = "password" onChange={this.onChange} value={this.state.password}/>
                    <br></br>
                    <button type="submit">Submit</button>
                </form>

II। हमारे कंस्ट्रक्टर, जिन्हें हम बचाना चाहते हैं usernameऔर passwordइसलिए, हम उन्हें आसानी से एक्सेस कर सकते हैं:

constructor(props) {
    super(props);
    this.state = {
        username: '',
        password: ''
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
}

III। केवल एक onChangeघटना के साथ दिलचस्प और "सामान्य" हैंडल इस पर आधारित है:

onChange(event) {
    let inputName = event.target.name;
    let value = event.target.value;

    this.setState({[inputName]:value});


    event.preventDefault();
}

मुझे समझाने दो:

1. जब किसी परिवर्तन का पता लगाया onChange(event)जाता है उसे कहा जाता है

2. फिर हम क्षेत्र और उसके मूल्य का नाम पैरामीटर प्राप्त करते हैं:

let inputName = event.target.name; ex: username

let value = event.target.value; ex: itsgosho

3. नाम पैरामीटर पर आधारित हम निर्माण में राज्य से अपना मूल्य प्राप्त करते हैं और इसे मूल्य के साथ अद्यतन करते हैं:

this.state['username'] = 'itsgosho'

4. यहां ध्यान देने वाली बात यह है कि क्षेत्र का नाम राज्य में हमारे पैरामीटर के साथ मेल खाना चाहिए

आशा है कि मैंने किसी तरह किसी की मदद की :)


0

आपके राज्य की कुंजी आपके इनपुट फ़ील्ड के नाम के समान होनी चाहिए। फिर आप इसे हैंडल विधि में कर सकते हैं;

this.setState({
        [event.target.name]: event.target.value
});

-1

हाय ssorallen जवाब में सुधार हुआ है । आपको फ़ंक्शन को बाँधने की आवश्यकता नहीं है क्योंकि आप इसके बिना इनपुट तक पहुंच सकते हैं।

var Hello = React.createClass({
    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
             <div>{total}<br/>
                  <input type="text" 
                    value={this.state.input1}
                    id="input1"  
                    onChange={this.handleChange} />
                 <input type="text" 
                    value={this.state.input2}
                    id="input2" 
                    onChange={this.handleChange} />
            </div>
       );
   },
   handleChange: function (name, value) {
       var change = {};
       change[name] = value;
       this.setState(change);
   }
});

React.renderComponent(<Hello />, document.getElementById('content'));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.