প্রতিক্রিয়া এটি.সেটস্টেট কোনও ফাংশন নয়


288

আমি প্রতিক্রিয়াতে নতুন এবং আমি একটি এপিআই দিয়ে কাজ করে একটি অ্যাপ লেখার চেষ্টা করছি। আমি এই ত্রুটিটি পেতে থাকি:

TypeError: this.setState কোনও ফাংশন নয়

আমি যখন API এর প্রতিক্রিয়াটি হ্যান্ডেল করার চেষ্টা করি। আমার সন্দেহ হয় যে এই বাঁধাইয়ের সাথে এটি কিছু ভুল হয়েছে তবে কীভাবে এটি ঠিক করবেন তা আমি বুঝতে পারি না। আমার উপাদানগুলির কোড এখানে:

var AppMain = React.createClass({
    getInitialState: function() {
        return{
            FirstName: " "
        };
    },
    componentDidMount:function(){
        VK.init(function(){
            console.info("API initialisation successful");
            VK.api('users.get',{fields: 'photo_50'},function(data){
                if(data.response){
                    this.setState({ //the error happens here
                        FirstName: data.response[0].first_name
                    });
                    console.info(this.state.FirstName);
                }

            });
        }, function(){
        console.info("API initialisation failed");

        }, '5.34');
    },
    render:function(){
        return (
            <div className="appMain">
            <Header  />
            </div>
        );
    }
});

উত্তর:


348

কলব্যাকটি অন্য প্রসঙ্গে তৈরি হয়েছে। আপনাকে করার প্রয়োজন bindথেকে thisঅর্ডার কলব্যাক ভিতরে এক্সেস আছে করার জন্য:

VK.api('users.get',{fields: 'photo_50'},function(data){
    if(data.response){
        this.setState({ //the error happens here
            FirstName: data.response[0].first_name
        });
        console.info(this.state.FirstName);
    }

}.bind(this));

সম্পাদনা: দেখে মনে হচ্ছে আপনাকে উভয় initএবং apiকল উভয়কেই আবদ্ধ করতে হবে :

VK.init(function(){
        console.info("API initialisation successful");
        VK.api('users.get',{fields: 'photo_50'},function(data){
            if(data.response){
                this.setState({ //the error happens here
                    FirstName: data.response[0].first_name
                });
                console.info(this.state.FirstName);
            }

        }.bind(this));
    }.bind(this), function(){
    console.info("API initialisation failed");

    }, '5.34');

@ ট্রাভিসরিডার, না। টিউটোরিয়ালে বাইন্ডের উল্লেখ নেই।
টর হগেন

8
সেখানে সম্ভবত 2.5 বছর আগে ছিল। 😁
ট্র্যাভিস রেডার

1
আমি সমস্যাটি সমাধান করতে তীর ফাংশনটি ব্যবহার করেছি। সহায়তার জন্য ধন্যবাদ
তরুণ নাগপাল

"কলব্যাকটি অন্য একটি প্রসঙ্গে তৈরি করা হয়েছে" এর অর্থ কী কেউ আরও বিশদভাবে বলতে পারে?
এসবি

135

আপনি ES6 তীর ফাংশন সহ .bind (এটি) এর প্রয়োজনীয়তা এড়াতে পারেন।

VK.api('users.get',{fields: 'photo_50'},(data) => {
        if(data.response){
            this.setState({ //the error happens here
                FirstName: data.response[0].first_name
            });
            console.info(this.state.FirstName);
        }

    });

1
এটি ভাল কাজ করে। আসলে, ফাংশনটির কীওয়ার্ডটি এস -6-এর কোনও ফাইলে প্রদর্শিত হবে না।
জেচেন___

6
আপনার উত্তরটি আমাকে সহায়তা করেছে :-) একটি ES6 শ্রেণি এবং আরএন 0.34 ব্যবহার করে, আমি "এটি" একটি কলব্যাক ফাংশনটিতে আবদ্ধ করার দুটি উপায় পেয়েছি। 1) onChange={(checked) => this.toggleCheckbox()}, 2) onChange={this.toggleCheckbox.bind(this)}
দেবদনকে

যতক্ষণ আপনার পুরানো ব্রাউজারগুলি সমর্থন করার প্রয়োজন হয় না এটি এটি ভাল।
ব্যবহারকারী

নিখুঁত সমাধান
হিতেশ সাহু

2
জিএমএসএফ, এই দুটি সমাধান কাজ করে কারণ ক) আপনি যখন .bind(this)এটি করেন তখন thisএটি প্যারেন্ট প্রসঙ্গটির মান নির্ধারণ করে যেখানে this.toggleCheckbox()থেকে ডাকা হয়, অন্যথায় thisএটি যেখানে সম্পাদিত হয়েছিল তা উল্লেখ করবে। খ) চর্বিযুক্ত তীর সমাধানটি কার্যকর করে কারণ এটি এর মান ধরে রাখে this, সুতরাং এটি হিংস্রভাবে এর মান পরিবর্তন না করে আপনাকে সহায়তা করছে this। জাভাস্ক্রিপ্টে, thisকেবল বর্তমান স্কোপকে বোঝায়, সুতরাং আপনি যদি কোনও ফাংশন লিখেন, thisতবে সেই ফাংশনটি। আপনি যদি এটির ভিতরে কোনও ফাংশন রাখেন তবে thisসেই শিশুটির ভিতরে রয়েছে।
চর্বিযুক্ত

37

আপনি পদ্ধতিটি thisচালুর আগে আপনি একটি রেফারেন্সও সংরক্ষণ করতে পারেন api:

componentDidMount:function(){

    var that = this;

    VK.init(function(){
        console.info("API initialisation successful");
        VK.api('users.get',{fields: 'photo_50'},function(data){
            if(data.response){
                that.setState({ //the error happens here
                    FirstName: data.response[0].first_name
                });
                console.info(that.state.FirstName);
            }
        });
    }, function(){
        console.info("API initialisation failed");

    }, '5.34');
},

32

প্রতিক্রিয়া এটি সমস্ত পদ্ধতিতে এটি আবদ্ধ হওয়ার প্রস্তাব দেয় যা classস্ব-স্ব পরিবর্তে এটির ব্যবহার করতে হবে function

constructor(props) {
    super(props)
    this.onClick = this.onClick.bind(this)
}

 onClick () {
     this.setState({...})
 }

অথবা আপনি arrow functionপরিবর্তে ব্যবহার করতে পারেন ।


14

আপনাকে কেবল আপনার ইভেন্টটি বাঁধতে হবে

প্রাক্তন জন্য

// place this code to your constructor

this._handleDelete = this._handleDelete.bind(this);

// and your setState function will work perfectly

_handleDelete(id){

    this.state.list.splice(id, 1);

    this.setState({ list: this.state.list });

    // this.setState({list: list});

}

10

এখন ES6 এর তীর ফাংশনটি রয়েছে এটি যদি সহায়ক হয় তবে আপনি যদি সত্যিই বাঁধার (এই) অভিব্যক্তিটি দিয়ে বিভ্রান্ত করেন তবে আপনি তীর ফাংশনটি চেষ্টা করতে পারেন

আমি এইভাবে করি।

componentWillMount() {
        ListApi.getList()
            .then(JsonList => this.setState({ List: JsonList }));
    }

 //Above method equalent to this...
     componentWillMount() {
         ListApi.getList()
             .then(function (JsonList) {
                 this.setState({ List: JsonList });
             }.bind(this));
 }

8

আপনি যদি তীর ফাংশনটি ব্যবহার করেন তবে আপনাকে এটিকে স্থানীয় ভেরিয়েবলের কাছে বরাদ্দ দেওয়ার দরকার নেই। তীর ফাংশনগুলি স্বয়ংক্রিয়ভাবে বাঁধাই লাগে এবং আপনি স্কোপ সম্পর্কিত সমস্যাগুলি থেকে দূরে থাকতে পারেন।

নীচে কোডটি বিভিন্ন পরিস্থিতিতে কীভাবে তীর ফাংশন ব্যবহার করবেন তা ব্যাখ্যা করে

componentDidMount = () => {

    VK.init(() => {
        console.info("API initialisation successful");
        VK.api('users.get',{fields: 'photo_50'},(data) => {
            if(data.response){
                that.setState({ //this available here and you can do setState
                    FirstName: data.response[0].first_name
                });
                console.info(that.state.FirstName);
            }
        });
    }, () => {
        console.info("API initialisation failed");

    }, '5.34');
 },

5

এখন es6 / 7 এর প্রতিক্রিয়া হিসাবে আপনি তীর ফাংশনটির সাথে ফাংশনটিকে বর্তমান প্রসঙ্গে আবদ্ধ করতে পারেন, অনুরোধ করতে পারেন এবং প্রতিশ্রুতিগুলি সমাধান করুন:

listMovies = async () => {
 const request = await VK.api('users.get',{fields: 'photo_50'});
 const data = await request.json()
 if (data) {
  this.setState({movies: data})
 }
}

এই পদ্ধতির সাহায্যে আপনি সহজেই উপাদান ফাংশন ডিডমাউন্টটিতে এই ফাংশনটি কল করতে পারেন এবং আপনার রেন্ডার ফাংশনে আপনার এইচটিএমএল রেন্ডার করার আগে ডেটা অপেক্ষা করতে পারেন।

আমি আপনার প্রকল্পের আকারটি জানি না তবে আমি ব্যক্তিগতভাবে এই উপাদানটির বর্তমান অবস্থা ব্যবহার করে ডেটাগুলি ব্যবহারের জন্য পরামর্শ দিই। আপনার জন্য বাহ্যিক অবস্থা যেমন রেডাক্স বা ফ্লাক্স বা অন্য কিছু ব্যবহার করা উচিত।


5

তীর ফাংশনগুলি ব্যবহার করুন, যেমন তীর ফাংশনগুলি প্যারেন্ট স্কোপকে নির্দেশ করে এবং এটি উপলব্ধ থাকবে। (বাইন্ড টেকনিকের বিকল্প)


1
একটি দুর্দান্ত সংযোগ সমাধান
চুন

পদ্ধতিটিতে কলটিতে তীর ফাংশন হিসাবে ডাকা হলেও একই সমস্যা থাকলেও আমি অনুমান করি যে আমাকে রাষ্ট্রীয় ফাংশনটি বাস্তবায়ন করতে হবে এবং আমি ঠিক কী করেছি
কারমিন তম্বাসিয়া

3

এখানে এই প্রসঙ্গে পরিবর্তন করা হচ্ছে। প্রতিক্রিয়া শ্রেণীর প্রসঙ্গ রাখতে তীর ফাংশন ব্যবহার করুন।

        VK.init(() => {
            console.info("API initialisation successful");
            VK.api('users.get',{fields: 'photo_50'},(data) => {
                if(data.response){
                    this.setState({ //the error happens here
                        FirstName: data.response[0].first_name
                    });
                    console.info(this.state.FirstName);
                }

            });
        }, function(){
        console.info("API initialisation failed");

        }, '5.34');

1

যদি আপনি এটি করছেন এবং এখনও কোনও সমস্যা রয়েছে তবে আমার সমস্যা হ'ল আমি দুটি ভেরিয়েবলকে একই নামে ডাকছিলাম।

companiesফায়ারবেস থেকে আমার কাছে একটি বস্তু আনা হয়েছিল এবং তারপরে ফোন করার চেষ্টা করছিলাম this.setState({companies: companies})- এটি সুস্পষ্ট কারণে কাজ করছে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.