प्रतिक्रिया, ES6 - getInitialState को एक सादे जावास्क्रिप्ट वर्ग पर परिभाषित किया गया था


115

मेरे पास निम्नलिखित घटक हैं ( radioOther.jsx):

 'use strict';

 //module.exports = <-- omitted in update

   class RadioOther extends React.Component {

     // omitted in update 
     // getInitialState() {
     //    propTypes: {
     //        name: React.PropTypes.string.isRequired
     //    }
     //    return {
     //       otherChecked: false
     //   }
     // }

     componentDidUpdate(prevProps, prevState) {
         var otherRadBtn = this.refs.otherRadBtn.getDOMNode();

         if (prevState.otherChecked !== otherRadBtn.checked) {
             console.log('Other radio btn clicked.')
             this.setState({
                 otherChecked: otherRadBtn.checked,
             });
         }
     }

     onRadChange(e) {
         var input = e.target;
         this.setState({
             otherChecked: input.checked
         });
     }

     render() {
         return (
             <div>
                 <p className="form-group radio">
                     <label>
                         <input type="radio"
                                ref="otherRadBtn"
                                onChange={this.onRadChange}
                                name={this.props.name}
                                value="other"/>
                         Other
                     </label>
                     {this.state.otherChecked ?
                         (<label className="form-inline">
                             Please Specify:
                             <input
                                 placeholder="Please Specify"
                                 type="text"
                                 name="referrer_other"
                                 />
                         </label>)
                         :
                         ('')
                     }
                 </p>
             </div>
         )
     }
 };

ECMAScript6 का उपयोग करने से पहले सब ठीक था, अब मुझे 1 त्रुटि, 1 चेतावनी मिल रही है और मेरे पास एक फॉलोअप प्रश्न है:

त्रुटि: बिना पढ़ा हुआ टाइपर्रर: प्रॉपर्टी को 'null के अन्य अनियंत्रित' नहीं पढ़ सकता

चेतावनी: getInitialState को RadioOther पर परिभाषित किया गया, जो एक सामान्य जावास्क्रिप्ट वर्ग है। यह केवल React.createClass का उपयोग करके बनाई गई कक्षाओं के लिए समर्थित है। क्या आपको इसके बजाय एक राज्य संपत्ति को परिभाषित करने का मतलब था?


  1. क्या कोई देख सकता है कि त्रुटि कहाँ है, मुझे पता है कि यह DOM में सशर्त विवरण के कारण है, लेकिन जाहिर है कि मैं इसके प्रारंभिक मूल्य को सही ढंग से घोषित नहीं कर रहा हूं?

  2. क्या मुझे getInitialState को स्थिर बनाना चाहिए

  3. अगर मेरी इंक्रीप्ट घोषित करने के लिए उपयुक्त जगह है, तो getInitialState सही नहीं है?

अपडेट करें:

   RadioOther.propTypes = {
       name: React.PropTypes.string,
       other: React.PropTypes.bool,
       options: React.PropTypes.array }

   module.exports = RadioOther;

यह कोड:

     constructor(props) {
         this.state = {
             otherChecked: false,
         };
     }

उत्पादन करता है "Uncaught ReferenceError: this is not defined", और नीचे सही करता है

     constructor(props) {
     super(props);
         this.state = {
             otherChecked: false,
         };
     }

लेकिन अब, दूसरे बटन पर क्लिक करने से अब त्रुटि उत्पन्न होती है:

Uncaught TypeError: Cannot read property 'props' of undefined


1
ईएस 6 कक्षाओं के लिए अन्य परिवर्तन यह है कि उदाहरण के लिए तरीके "ऑटो-बाउंड" नहीं हैं, जिसका अर्थ है जब आप किसी फ़ंक्शन को पास करते हैं onChange={this.onRadChange}, thisतो उदाहरण के लिए संदर्भित नहीं होता onRadChangeहै जब कॉल किया जाता है। आपको कॉलबैक को बांधने renderया निर्माणकर्ता में करने की आवश्यकता है onChange={this.onRadChange.bind(this)}:।
रॉस एलन

जवाबों:


239
  • getInitialStateES6 कक्षाओं में उपयोग नहीं किया जाता है। इसके बजाय this.stateकंस्ट्रक्टर में असाइन करें ।
  • propTypes एक स्थिर वर्ग चर होना चाहिए या कक्षा को सौंपा जाना चाहिए, इसे घटक उदाहरणों को नहीं सौंपा जाना चाहिए।
  • सदस्य विधियाँ ES6 कक्षाओं में "ऑटो-बाउंड" नहीं हैं। कॉलबैक के रूप में उपयोग किए जाने वाले तरीकों के लिए, या तो क्लास प्रॉपर्टी इनिशियलाइज़र का उपयोग करें या कंस्ट्रक्टर में बाध्य उदाहरण निर्दिष्ट करें।
export default class RadioOther extends React.Component {

  static propTypes = {
    name: React.PropTypes.string.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      otherChecked: false,
    };
  }

  // Class property initializer. `this` will be the instance when
  // the function is called.
  onRadChange = () => {
    ...
  };

  ...

}

ES6 क्लासेस के बारे में रिएक्ट के डॉक्यूमेंटेशन में और देखें: किसी फंक्शन को क्लास में बदलना


एक वर्ष और अब आपको मिल सकता है: Uncaught TypeError: Cannot read property 'bind' of undefinedत्रुटि कोई विचार?
जेमी हटबर

@JamieHutber क्या आप अपने कोड के साथ एक नया प्रश्न बना सकते हैं? यदि विधि को कक्षा में परिभाषित किया गया है, तो मुझे नहीं पता कि आपको वह त्रुटि क्यों मिलेगी।
रॉस एलन

सुझाव के लिए धन्यवाद, @KennethWorden। मैंने रिएक्ट डॉक्स के लिए एक मुद्दा खोला: github.com/facebook/react/issues/7746
रॉस एलन

क्या आप उन्हें जगह में बाँधने का मतलब है, जैसा कि आप ऊपर दिखा रहे हैं? यह काम करता है, बिल्कुल। ओह, जावास्क्रिप्ट!
jomofrodo

@jomofrodo यह अस्पष्ट है, इस ओर इशारा करने के लिए धन्यवाद। मेरा मतलब था कि renderआप ऐसा कुछ कर सकते हैं onClick={this.doFoo.bind(this)}, लेकिन मैंने जानबूझकर इसे कोड में शामिल नहीं किया है क्योंकि यह सबसे कम कुशल तरीका है क्योंकि renderइसे अक्सर कॉल किया जा सकता है और प्रत्येक कॉल पर नए फ़ंक्शन बनाए जाएंगे। मैं उस भाषा को उत्तर से हटा दूंगा।
रॉस एलन

4

रॉस के जवाब में जोड़ना ।

आप नए ES6 एरो फंक्शन का इस्तेमाल ऑनकेंज प्रॉपर्टी पर भी कर सकते हैं

यह कार्यात्मक रूप से this.onRadChange = this.onRadChange.bind(this);निर्माता में परिभाषित करने के बराबर है लेकिन मेरी राय में अधिक संक्षिप्त है।

आपके मामले में रेडियो बटन नीचे की तरह दिखेगा।

<input type="radio"
       ref="otherRadBtn"
       onChange={(e)=> this.onRadChange(e)}
       name={this.props.name}
       value="other"/>

अपडेट करें

यह "अधिक संक्षिप्त" विधि @Ross एलन के उत्तर में उल्लिखित विकल्पों की तुलना में कम कुशल है क्योंकि यह render()विधि को हर बार एक नया कार्य उत्पन्न करता है


1
यह समाधान कार्यात्मक रूप से सही है, लेकिन यह प्रत्येक कॉल पर एक नया फ़ंक्शन बनाता है render(जिसे कई बार कहा जा सकता है)। क्लास प्रॉपर्टी इनिशियलाइज़र या कंस्ट्रक्टर में बाइंडिंग का उपयोग करके, घटक के निर्माण पर केवल एक नया बन्धन फ़ंक्शन बनाया जाता है और इस दौरान कोई नया फ़ंक्शंस नहीं बनाया जाता है render
रॉस एलन

1

यदि आप बैबल-प्लगइन-ट्रांसफॉर्म-क्लास-प्रॉपर्टीज़ या बैबल-प्रीसेट-स्टेज -2 (या स्टेज -1, या स्टेज -0) का उपयोग कर रहे हैं, तो आप इस सिंटैक्स का उपयोग कर सकते हैं:

class RadioOther extends React.Component {

  static propTypes = {
    name: React.PropTypes.string,
    ...
  };

  state = {
      otherChecked: false,
  };

  onRadChange = () => {
    ...
  };

  ...

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.