React - uncaught TypeError: अपरिभाषित की संपत्ति 'setState' नहीं पढ़ सकता है


316

मुझे निम्नलिखित त्रुटि प्राप्त हो रही है

अनक्रीप्ड टाइपरर: अपरिभाषित की संपत्ति 'सेटस्टेट' को नहीं पढ़ सकता है

कंस्ट्रक्टर में डेल्टा बांधने के बाद भी।

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count : 1
        };

        this.delta.bind(this);
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
    }
}

4
ES6 में, आप इस समस्या को ठीक करने के लिए फ़ंक्शन घोषणा के लिए तीर फ़ंक्शन का उपयोग कर सकते हैं।
ताल

^ यह सही उत्तर होना चाहिए
जोर्डेक

मैंने अपनी प्रतिक्रिया समारोह को ES6 में बदल दिया, और ह्रेरी, इसके काम कर रहा है।
अश्विनी गर्ग

जवाबों:


448

यह this.deltaबाध्य नहीं होने के कारण है this

this.delta = this.delta.bind(this)कंस्ट्रक्टर में सेट करने के लिए :

constructor(props) {
    super(props);

    this.state = {
        count : 1
    };

    this.delta = this.delta.bind(this);
}

वर्तमान में, आप बाइंड कह रहे हैं। लेकिन बाइंड एक बाध्य फ़ंक्शन देता है। आपको फ़ंक्शन को उसके बाध्य मान पर सेट करने की आवश्यकता है।


186
धरती पर ईएस 6 कक्षाओं का क्या मतलब है अगर उनके तरीकों में उचित शंक्वाकार thisबंधन नहीं है , और फिर उनके संदर्भ को सीधे उनकी परिभाषा में बांधने के लिए एक वाक्यविन्यास भी नहीं है !?
अगमलाउंटर

1
मैं आपकी बात समझता हूं लेकिन अगर मैं कंपोनेंटविलामाउंट () में कोड लिखता हूं तो मैं कैसे
बांधूंगा

1
@sureshpareek एक बार जब आप अपने फ़ंक्शन को कंस्ट्रक्टर में बांधते हैं, तो इसे तब बाध्य किया जाना चाहिए जब आप इसे किसी भी जीवनचक्र हुक से कहते हैं।
लेवी फुलर

4
Android / जावा दुनिया से आ रहा हूँ मैं चकित हूँ
ट्यूडर

3
@ लेम्ब्डा कार्यों के एग्मलाउन्चर उपयोग का अर्थ यह है। यदि आप कोड के deltaरूप delta = () => { return this.setState({ count: this.state.count++ }); };में परिभाषित करते हैं तो यह भी काम करेगा। यहाँ समझाया गया: hackernoon.com/…
। Rhoda

144

में ES7 + (ES2016) आप प्रयोगात्मक उपयोग कर सकते हैं समारोह बाँध वाक्य रचना ऑपरेटर ::बाँध करने के लिए। यह एक सिंथेटिक चीनी है और डेविन ट्राटन के उत्तर के समान ही करेगा।

फिर आप को फिर से लिखने कर सकते हैं this.delta = this.delta.bind(this);करने के लिएthis.delta = ::this.delta;


के लिए ES6 + (ES2015) आप भी ES6 का उपयोग कर सकते हैं + तीर समारोह ( =>) का उपयोग करने में सक्षम हो this

delta = () => {
    this.setState({
        count : this.state.count + 1
    });
}

क्यों ? मोज़िला डॉक से:

तीर के कार्यों तक, प्रत्येक नए फ़ंक्शन ने अपने स्वयं के इस मूल्य को परिभाषित किया [...]। यह प्रोग्रामिंग की एक वस्तु-उन्मुख शैली से परेशान साबित हुआ।

एरो फ़ंक्शंस संलग्न करने के संदर्भ के इस मूल्य को पकड़ते हैं [...]


3
इसे विस्तार से वर्णन करते हुए अच्छा लेख: reactkungfu.com/2015/07/…
Edo

सिंटेक्स के अलावा, एक के ऊपर एक का उपयोग करने का क्या फायदा है?
जेरेमी डी

2
बाइंड सिंटेक्स क्लीनर होता है क्योंकि आप अपनी विधि का सामान्य दायरा रख सकते हैं।
फाबिएन सा

बाइंड सिंटैक्स ES2016 या ES2017 का हिस्सा नहीं है।
फेलिक्स क्लिंगिंग

2
@stackoverflow किसी भी जवाब के लिए एक इनाम जोड़ने की क्षमता जोड़ना चाहिए।
गाबे

29

ES5 और ES6 वर्ग के बीच एक अंतर है। इसलिए, कार्यान्वयन के बीच भी थोड़ा अंतर होगा।

यहाँ ES5 संस्करण है:

var Counter = React.createClass({
    getInitialState: function() { return { count : 1 }; },
    delta: function() {
        this.setState({
            count : this.state.count++
        });
    },
    render: function() {
        return (
            <div>
              <h1>{this.state.count}</h1>
              <button onClick={this.delta}>+</button>
            </div>
            );
    }
});

और यहाँ ES6 संस्करण है:

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = { count : 1 };
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
              <h1>{this.state.count}</h1>
              <button onClick={this.delta.bind(this)}>+</button>
            </div>
            );
    }
}

बस कार्यान्वयन में वाक्यविन्यास अंतर के बगल में सावधान रहें, घटना हैंडलर बाइंडिंग में अंतर है।

ES5 संस्करण में, यह है

              <button onClick={this.delta}>+</button>

ES6 संस्करण में, यह है:

              <button onClick={this.delta.bind(this)}>+</button>

जेएसएक्स में तीर के कार्यों या बंधन का उपयोग करना एक बुरा अभ्यास है। stackoverflow.com/questions/36677733/…
फाबिन सा

24

प्रतिक्रिया में ES6 कोड का उपयोग करते समय हमेशा तीर फ़ंक्शन का उपयोग करें, क्योंकि यह संदर्भ स्वचालित रूप से इसके साथ बाँधा जाता है

इसे इस्तेमाल करो:

(videos) => {
    this.setState({ videos: videos });
    console.log(this.state.videos);
};

के बजाय:

function(videos) {
    this.setState({ videos: videos });
    console.log(this.state.videos);
};

2
यदि तीर फ़ंक्शन और पैरामीटर चर का उपयोग कर रहा है का उपयोग कुंजी चर के समान होता है, तो मैं इसका उपयोग करने की सलाह this.setState({videos});
दूंगा

मेरे लिए यही किया। मैं नोड के लिए नया हूँ, और axios मॉड्यूल के लिए डॉक्स प्रतिक्रिया और सेटस्टेट के साथ असंगत था
dabobert

20

आपको कुछ भी बांधने की ज़रूरत नहीं है, बस एरो फ़ंक्शंस का उपयोग करें:

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count: 1
        };

    }
    //ARROW FUNCTION
    delta = () => {
        this.setState({
            count: this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
    }
}

यह काम करता है क्या अंतर है कृपया क्यों है?
ऋधा रिज्जैग

4
तीर फ़ंक्शन के साथ यह गुंजाइश संदर्भ से विरासत में मिली है। नियमित फ़ंक्शंस के साथ, यह हमेशा निकटतम फ़ंक्शन को संदर्भित करता है, जबकि एरो फ़ंक्शंस के साथ यह समस्या हटा दी जाती है, और आपको उस संस्करण को लिखने की आवश्यकता नहीं होगी = कभी भी। @RezzagRidha
रुइज़

1
2019 तक यह जाने का रास्ता है (Y)
MH

6

आप भी उपयोग कर सकते हैं:

<button onClick={()=>this.delta()}>+</button>

या:

<button onClick={event=>this.delta(event)}>+</button>

अगर आप कुछ पारामों को पार कर रहे हैं ..


जेएसएक्स
गेबे

5

आपको इसे कंस्ट्रक्टर से बांधने की आवश्यकता है और याद रखें कि कंस्ट्रक्टर में परिवर्तन करने के लिए सर्वर को पुनरारंभ करने की आवश्यकता है। या फिर, आप उसी त्रुटि के साथ समाप्त हो जाएंगे।


1
अपने बालों को बाहर निकाल रहा था क्योंकि मैं सर्वर को पुनरारंभ नहीं करता था।
कर्टकोर्बेट

5

आपको अपने तरीकों को 'इस' (डिफ़ॉल्ट ऑब्जेक्ट) के साथ बांधना होगा। तो जो कुछ भी आपके कार्य को बांध सकता है, वह है।

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

    this.handleChecked = this.handleChecked.bind(this);
}

handleChecked(){
    this.setState({
        checked: !(this.state.checked)
    })
}

render(){
    var msg;

    if(this.state.checked){
        msg = 'checked'
    }
    else{
        msg = 'not checked'
    }

    return (
        <div>               
            <input type='checkbox' defaultChecked = {this.state.checked} onChange = {this.handleChecked} />
            <h3>This is {msg}</h3>
        </div>
    );

4

इस त्रुटि को विभिन्न तरीकों से हल किया जा सकता है-

  • यदि आप ES5 सिंटैक्स का उपयोग कर रहे हैं , तो React js प्रलेखन के अनुसार आपको बाइंड विधि का उपयोग करना होगा ।

    उपरोक्त उदाहरण के लिए कुछ इस तरह:

    this.delta = this.delta.bind(this)

  • यदि आप ES6 सिंटैक्स का उपयोग कर रहे हैं , तो आपको बाइंड विधि का उपयोग करने की आवश्यकता नहीं है , आप इसे कुछ इस तरह से कर सकते हैं:

    delta=()=>{ this.setState({ count : this.state.count++ }); }


2

इस समस्या के दो समाधान हैं:

पहला समाधान आपके कंपोनेंट में एक कंस्ट्रक्टर जोड़कर आपके फंक्शन को bellow की तरह बांधने का है:

constructor(props) {
        super(props);

        ...

        this.delta = this.delta.bind(this);
    }

तो ऐसा करें:

this.delta = this.delta.bind(this); 

इसके अलावा:

this.delta.bind(this);

दूसरा समाधान इसके बजाय एक तीर फ़ंक्शन का उपयोग करना है:

delta = () => {
       this.setState({
           count : this.state.count++
      });
   }

वास्तव में एरो फंक्शन यह नहीं है कि यह स्वयं का है this। एरो फ़ंक्शंस को शाब्दिक रूप से bindउनके संदर्भ के रूप में देखा जाता है, इसलिए यह thisवास्तव में मूल संदर्भ को संदर्भित करता है ।

बाइंड फ़ंक्शन के बारे में अधिक जानकारी के लिए:

Bind फ़ंक्शन जावास्क्रिप्ट बाइंड () को समझना

तीर फ़ंक्शन के बारे में अधिक जानकारी के लिए:

जावास्क्रिप्ट ईएस 6 - एरो फ़ंक्शंस और लेक्सिकल this


1

जैसा कि मैंने नीचे उल्लेख किया है, आपको इस घटना के साथ नई घटना को बांधना होगा ...

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count : 1
        };

        this.delta = this.delta.bind(this);
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
      }
    }

1

जोड़ा जा रहा है

onClick = {this.delta.bind (यह)}

समस्या का समाधान करेंगे। यह त्रुटि तब आती है जब हम ES6 वर्ग के फ़ंक्शन को कॉल करने का प्रयास करते हैं, इसलिए हमें विधि को बांधने की आवश्यकता है।


1

इस कीवर्ड को बाइंड करने से बचने के लिए एरो फ़ंक्शन आपके जीवन को अधिक आसान बना सकता है । इस तरह:

 delta = () => {
       this.setState({
           count : this.state.count++
      });
   }

0

हालाँकि इस सवाल का हल पहले से ही था, मैं बस इसे साफ करने के लिए अपना हिस्सा देना चाहता हूं, उम्मीद है कि यह मदद कर सकता है:

/* 
 * The root cause is method doesn't in the App's context 
 * so that it can't access other attributes of "this".
 * Below are few ways to define App's method property
 */
class App extends React.Component {
  constructor() {
     this.sayHi = 'hello';
     // create method inside constructor, context = this
     this.method = ()=> {  console.log(this.sayHi) };

     // bind method1 in constructor into context 'this'
     this.method1 = this.method.bind(this)
  }

  // method1 was defined here
  method1() {
      console.log(this.sayHi);
  }

  // create method property by arrow function. I recommend this.
  method2 = () => {
      console.log(this.sayHi);
  }
   render() {
   //....
   }
}

0
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>

    <script src="https://unpkg.com/react@0.14.8/dist/react.min.js"></script>
    <script src="https://unpkg.com/react-dom@0.14.8/dist/react-dom.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

  </head>
  <body>
  <div id="root"></div>
    <script type="text/babel">

        class App extends React.Component{

            constructor(props){
                super(props);
                this.state = {
                    counter : 0,
                    isToggle: false
                }
            this.onEventHandler = this.onEventHandler.bind(this);   
            }

            increment = ()=>{
                this.setState({counter:this.state.counter + 1});
            }

            decrement= ()=>{
                if(this.state.counter > 0 ){
                this.setState({counter:this.state.counter - 1});    
                }else{
                this.setState({counter:0});             
                }
            }
            // Either do it as onEventHandler = () => {} with binding with this  // object. 
            onEventHandler(){
                this.setState({isToggle:!this.state.isToggle})
                alert('Hello');
            }


            render(){
                return(
                    <div>
                        <button onClick={this.increment}> Increment </button>
                        <button onClick={this.decrement}> Decrement </button>
                        {this.state.counter}
                        <button onClick={this.onEventHandler}> {this.state.isToggle ? 'Hi':'Ajay'} </button>

                    </div>
                    )
            }
        }
        ReactDOM.render(
        <App/>,
        document.getElementById('root'),
      );
    </script>
  </body>
  </html>

0

बस आपको अपने => से क्या करना है, अपने बाइंड स्टेटमेंट को बदल दें this.delta = this.delta.bind (इस) में है;


0
  1. राज्य की स्थिति की जांच करें कि क्या आप विशेष संपत्ति बनाते हैं या नहीं

this.state = {
            name: "",
            email: ""
            }
            
           
            
this.setState(() => ({ 
             comments: comments          //comments not available in state
             })) 

2. (इस) की जाँच करें यदि आप किसी फ़ंक्शन (यानी हैंडल क्रैन् चेंज) के अंदर सेटस्टैट कर रहे हैं, तो (या) चेक करें कि फ़ंक्शन इस या बाइंड फ़ंक्शन को बाँधता है या नहीं।

## इसे नीचे फ़ंक्शन के लिए बाध्य करने के 3 तरीके ##

//3 ways for binding this to the below function

handleNameChange(e) {  
     this.setState(() => ({ name }))
    }
    
// 1.Bind while callling function
      onChange={this.handleNameChange.bind(this)}
      
      
//2.make it as arrow function
     handleNameChange((e)=> {  
     this.setState(() => ({ name }))
     })
    
//3.Bind in constuctor 

constructor(props) {
        super(props)
        this.state = {
            name: "",
            email: ""
        }
        this.handleNameChange = this.handleNameChange.bind(this)
        }


0

यदि आपका ES5 सिंटैक्स उपयोग कर रहा है तो आपको इसे ठीक से बांधने की आवश्यकता है

this.delta = this.delta.bind(this)

और यदि आप ES6 का उपयोग कर रहे हैं और ऊपर आप तीर फ़ंक्शन का उपयोग कर सकते हैं, तो आपको इसे बाँधने () का उपयोग करने की आवश्यकता नहीं है

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