2017-01-05 13 views
8

में बटन को अक्षम कैसे मैं इस घटक है। लेकिन उपरोक्त कोड काम नहीं करता है। यह कहता है:React.js

add-item.component.js:78 Uncaught TypeError: Cannot read property 'value' of undefined

disabled={!this.input.value} पर इशारा करते हुए। मैं यहाँ क्या गलत कर सकता हूँ? मुझे लगता है कि शायद render विधि निष्पादित की गई है, तो शायद रेफ नहीं बनाया गया है। यदि, तो वर्कअराउंड क्या है?

उत्तर

18

refs का उपयोग नहीं सबसे अच्छा अभ्यास है क्योंकि यह डोम पढ़ता सीधे, यह प्रतिक्रिया के state बजाय उपयोग करना बेहतर है है। साथ ही, आपका बटन नहीं बदलेगा क्योंकि घटक को फिर से प्रस्तुत नहीं किया जाता है और इसकी प्रारंभिक स्थिति में रहता है।

आप setState एक साथ उपयोग कर सकते हैं एक onChange घटना श्रोता के साथ फिर से हर बार इनपुट क्षेत्र परिवर्तन घटक रेंडर करने के लिए:

// Input field listens to change, updates React's state and re-renders the component. 
<input onChange={e => this.setState({ value: e.target.value })} value={this.state.value} /> 

// Button is disabled when input state is empty. 
<button disabled={!this.state.value} /> 

यहाँ एक काम कर उदाहरण है:

class AddItem extends React.Component { 
 
    constructor() { 
 
    super(); 
 
    this.state = { value: '' }; 
 
    this.onChange = this.onChange.bind(this); 
 
    this.add = this.add.bind(this); 
 
    } 
 

 
    add() { 
 
    this.props.onButtonClick(this.state.value); 
 
    this.setState({ value: '' }); 
 
    } 
 

 
    onChange(e) { 
 
    this.setState({ value: e.target.value }); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div className="add-item"> 
 
     <input 
 
      type="text" 
 
      className="add-item__input" 
 
      value={this.state.value} 
 
      onChange={this.onChange} 
 
      placeholder={this.props.placeholder} 
 
     /> 
 
     <button 
 
      disabled={!this.state.value} 
 
      className="add-item__button" 
 
      onClick={this.add} 
 
     > 
 
      Add 
 
     </button> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <AddItem placeholder="Value" onButtonClick={v => console.log(v)} />, 
 
    document.getElementById('View') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id='View'></div>

+0

यह सही जवाब है! इनपुट के परिवर्तन पर अपडेट करने के लिए आंतरिक स्थिति का उपयोग किया जाना चाहिए और बटन को इसके खिलाफ जांच करनी चाहिए। +1 –

+0

this.state की एक सीमा है कि यह यूआई को फिर से प्रस्तुत करता है ताकि यदि आप किसी बच्चे के घटक में टेक्स्ट बॉक्स में टाइप कर रहे हों और ऑन चेंज ईवेंट से बंधे हों, तो यह टेक्स्टबॉक्स से फोकस खो देता है। यदि यह एक ही घटक में है तो यह ठीक है लेकिन जब बच्चे के घटक में उपयोग किया जाता है तो यह फोकस खो देता है। – Dynamic

+0

@ गतिशील ऐसा नहीं होना चाहिए। क्या आपके पास इसका एक उदाहरण है? –

2

आपको रेफरी के माध्यम से इनपुट का मूल्य निर्धारित नहीं करना चाहिए।

यहाँ नियंत्रित प्रपत्र घटकों के लिए प्रलेखन पर एक नजर डालें - https://facebook.github.io/react/docs/forms.html#controlled-components

संक्षेप

<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} /> 

में तो फिर तुम का उपयोग कर disabled={!this.state.value}

1

this.input है द्वारा विकलांग राज्य को नियंत्रित करने के लिए सक्षम हो जाएगा ref कॉलबैक को तब तक अपरिभाषित किया जाता है जब कॉलबैक कहा जाता है। अपने कन्स्ट्रक्टर में कुछ शुरुआती मूल्य पर this.input सेट करने का प्रयास करें।

the React docs on refs से, जोर मेरा:

the callback will be executed immediately after the component is mounted or unmounted

0

कुछ सामान्य तरीके हैं जो हम घटकों को नियंत्रित करते हैं प्रतिक्रिया होती है। enter image description here

लेकिन, मैंने इनमें से किसी भी का उपयोग नहीं किया है, मैंने अभी रेफरी को अंतर्निहित बच्चों को घटक में नामित करने के लिए उपयोग किया है।

class AddItem extends React.Component { 
 
    change(e) { 
 
     if ("" != e.target.value) { 
 
     this.button.disabled = false; 
 
     } else { 
 
     this.button.disabled = true; 
 
     } 
 
    } 
 

 
    add(e) { 
 
     console.log(this.input.value); 
 
     this.input.value = ''; 
 
     this.button.disabled = true; 
 
    } 
 

 
    render() { 
 
     return (
 
      <div className="add-item"> 
 
      <input type="text" className = "add-item__input" ref = {(input) => this.input=input} onChange = {this.change.bind(this)} /> 
 
      
 
      <button className="add-item__button" 
 
      onClick= {this.add.bind(this)} 
 
      ref={(button) => this.button=button}>Add 
 
      </button> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
ReactDOM.render(<AddItem/> , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>