javascript - ماهو - react ترجمة




React-uncaught TypeError: لا يمكن قراءة خاصية 'setState' غير محددة (12)

  1. تحقق من حالة التحقق من حالة ما إذا كنت تنشئ خاصية معينة أم لا

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

2. تحقق من (هذا) إذا كنت تقوم بتعيين setState داخل أي وظيفة (على سبيل المثال handleChange) ، تحقق مما إذا كانت الوظيفة مرتبطة بهذه الوظيفة أو أن تكون وظيفة السهم.

## 3 طرق لربط هذا بالوظيفة أدناه ##

this.delta.bind(this);

اتلقى الخطأ التالي

TypeError Uncaught: لا يمكن قراءة خاصية 'setState' غير محددة

حتى بعد دلتا الربط في المنشئ.

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>
        );
    }
}

تحتاج إلى ربط هذا المنشئ وتذكر أن التغييرات التي تم إجراؤها على المنشئ تحتاج إلى إعادة تشغيل الخادم. وإلا ، ستنتهي بنفس الخطأ.


على الرغم من أن هذا السؤال كان حلاً بالفعل ، فأنا أريد فقط أن أشارككم في حل المشكلة ، وآمل أن يساعد ذلك:

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

عند استخدام رمز ES6 في React ، استخدم دائمًا وظائف السهم ، لأن هذا السياق يرتبط به تلقائيًا

استخدم هذا:

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

بدلا من:

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

في ES7 + (ES2016) ، يمكنك استخدام عامل بناء جملة ربط الدالة التجريبية :: للربط. إنه سكر نحوي وسوف يفعل نفس الشيء مثل إجابة Davin Tryon.

يمكنك بعد ذلك إعادة كتابة هذا. this.delta = this.delta.bind(this); إلى this.delta = ::this.delta;

بالنسبة إلى ES6 + (ES2015) ، يمكنك أيضًا استخدام دالة سهم ES6 + ( => ) لتتمكن من استخدام this .

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

لماذا ا ؟ من وثيقة موزيلا:

حتى وظائف السهم ، حددت كل دالة جديدة هذه القيمة [...]. ثبت أن هذا مزعج مع أسلوب وجوه المنحى من البرمجة.

وظائف السهم التقاط هذه القيمة للسياق المحيط [...]


ليس عليك ربط أي شيء ، ما عليك سوى استخدام وظائف Arrow مثل هذا:

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>
        );
    }
}

هذا بسبب عدم ربط this.delta this .

لربط مجموعة this.delta = this.delta.bind(this) في المُنشئ:

constructor(props) {
    super(props);

    this.state = {
        count : 1
    };

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

حاليا ، أنت تتصل ربط. ولكن ربط إرجاع دالة منضمة. تحتاج إلى ضبط الوظيفة على قيمتها المنضمة.


هناك حلان لهذه المشكلة:

الحل الأول هو إضافة مُنشئ إلى المكون الخاص بك وربط وظيفتك مثل رفع الصوت عاليا:

/* 
 * 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() {
   //....
   }
}

افعل هذا:

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

    <script src="https://unpkg.com/[email protected]/dist/react.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
    <script src="https://unpkg.com/[email protected]/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>

بدلا من هذا:

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

الحل الثاني هو استخدام دالة سهم بدلاً من ذلك:

//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)
        }

في الواقع وظيفة السهم لا تربط انها تملك this . دالات السهم bind سياقها معجميًا ، this يشير في الواقع إلى السياق الأصلي .

لمزيد من المعلومات حول وظيفة الربط:

وظيفة الربط فهم JavaScript Bind ()

لمزيد من المعلومات حول وظيفة السهم:

hackernoon.com/…


يجب عليك ربط أساليبك بـ "هذا" (الكائن الافتراضي). لذلك مهما كانت وظيفتك قد تكون مرتبطة فقط في المنشئ.

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>
    );

يجب عليك ربط حدث جديد بهذه الكلمة الرئيسية كما ذكرت أدناه ...

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>
        );
      }
    }

يوجد اختلاف في السياق بين فئة 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>

constructor(props) {
        super(props);

        ...

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






reactjs