this.setState不是一个函数 [英] this.setState is not a function

查看:135
本文介绍了this.setState不是一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下组件,它保持在特定元素上触发事件时被更新的状态,当状态更新时,它被作为支持传递给另一个组件。我目前正在尝试为什么我收到以下错误this.setState不是一个功能,它很可能没有绑定到正确的上下文。但我不确定这一点,我这样做是对的吗?

 导出默认类SearchBox extends Component {

constructor(){
super()
console.log(search box imported);
this.state = {
results:[]
};
}

//this.setState({result:arrayExample})

searchGif(event){
if(event.keyCode == 13 ){
let inputVal = this.refs.query.value;
let xhr = new XMLHttpRequest();
xhr.open('GET','http://api.giphy.com/v1/gifs/search?q='+inputVal+'&api_key=dc6zaTOxFJmzC',true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4&& xhr.status == 200){
// this.response = JSON.parse xhr.responseText);
let returnedObj = JSON.parse(xhr.responseText);
//console.log (returnedObj.data);
let response = returnedObj.data.map(function(record){
let reformattedArray = {key:record.id,
id:record.id,
thumbnailUrl:record。 images.fixed_height_small_still.url
};
return reformattedArray;
});
console.log(response);
this.setState({results:response});
}
}
xhr.send();
}
}


render(){

return(
< div>
&输入className =search-inputref =queryonKeyDown = {this.searchGif.bind(this)} name =searchplaceholder =Search/>
< GifSwatch data = {this。 state.results} />
< / div>
);
}
}

编辑:
我只是意识到在onreadyStateChange函数时,上下文被改变,所以我在searchGif

  searchGif(){ 
//其他逻辑
var self = this;
xhr.onreadystatechange = function(){
// ajax logic
self.setState({results:repsonse});
}
}


解决方案

你正在输入React类这个上下文。绑定它,也绑定在异步回调函数中。

 构造函数(道具){
超(道具) );
console.log(search box imported);
this.state = {
results:[]
};
this.searchGif = this.searchGif.bind(this);
}

searchGif(event){
// ...代码这里
xhr.onreadystatechange =()=> {
// ...代码这里
this.setState();
}
}

关于箭头函数的很棒的事情是他们绑定你的上下文你和语法也很棒。缺点是浏览器支持。确保您有一个polyfil或编译过程将其编译为ES5语法以进行跨浏览器性能。



如果您不能做任何一个,那么只需创建一个阴影变量你的这个上下文在异步 onreadystatechange 函数之外,并使用它而不是这个


I have the following component, which maintains the state that gets updated when the event is fired on the an specific element and when the state is updated it is passed down as a prop to another component. I am currently trying why i get the following error "this.setState is not a function", its most likely not binded to the right context. But i am unsure of this, am i doing this right?

export default class SearchBox extends Component{

    constructor(){
        super()
        console.log("search box imported");
        this.state = {
            results:[]
        };
    }

    //this.setState({result: arrayExample})

    searchGif(event) {
        if(event.keyCode == 13){
            let inputVal = this.refs.query.value;
            let xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://api.giphy.com/v1/gifs/search?q='+inputVal+'&api_key=dc6zaTOxFJmzC', true);
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200){
                    // this.response = JSON.parse(xhr.responseText);
                    let returnedObj = JSON.parse(xhr.responseText);
                    //console.log(returnedObj.data);
                    let response = returnedObj.data.map(function(record){
                        let reformattedArray =  {   key: record.id,
                                                    id: record.id,
                                                    thumbnailUrl: record.images.fixed_height_small_still.url
                                                };
                                                return reformattedArray;
                    });
                    console.log(response);
                    this.setState({results: response});
                }
            }
            xhr.send();
        }
    }


    render(){

        return(
            <div>   
                <input className="search-input" ref="query" onKeyDown={this.searchGif.bind(this)} name="search" placeholder="Search"/>
                <GifSwatch data={this.state.results} />
            </div>
        );
    }
}

EDIT: I just realized the context gets changed when "onreadyStateChange" function, so i did the following in searchGif

searchGif(){
   //other logic
   var self = this;
   xhr.onreadystatechange = function(){
    //ajax logic
    self.setState({results: repsonse});
   }
}

解决方案

You are losing the React class this context. Bind it, and also bind it in the async callback function too.

constructor(props){
    super(props);
    console.log("search box imported");
    this.state = {
        results:[]
    };
    this.searchGif = this.searchGif.bind(this);
}

searchGif(event) {
    // ... code here
    xhr.onreadystatechange = () => {
    // ... code here
        this.setState();
    }
}

awesome thing about arrow functions is they bind your context for you and the syntax is awesome too. downside is browser support. Make sure you have a polyfil or a compile process to compile it into ES5 syntax for cross browser performance.

If you cant do either of those then just make a shadow variable of your this context outside of the async onreadystatechange function and use it instead of this.

这篇关于this.setState不是一个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆