【问题标题】:this.setState is not a function [duplicate]this.setState 不是函数[重复]
【发布时间】:2016-01-27 16:16:03
【问题描述】:

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

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

编辑: 我刚刚意识到当“onreadyStateChange”函数时上下文发生了变化,所以我在 searchGif 中做了以下操作

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

【问题讨论】:

  • var self = this; 已被箭头函数淘汰。既然你有 ES6,你可以使用它让你的缩进更清晰。

标签: javascript reactjs ecmascript-6


【解决方案1】:

您正在丢失 React 类 this 上下文。绑定它,也绑定在异步回调函数中。

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

箭头函数很棒的一点是它们为您绑定了上下文,而且语法也很棒。缺点是浏览器支持。确保你有一个 polyfil 或一个编译过程来将它编译成 ES5 语法以获得跨浏览器的性能。

如果您不能执行其中任何一项,那么只需在异步 onreadystatechange 函数之外创建 this 上下文的影子变量,并使用它而不是 this


编辑

现在大多数编译器都使用箭头处理类的绑定方法(不指定 babel 转换...等),您也可以通过这种方式分配状态而无需构造函数

export default class SearchBox extends Component {
  state = { 
    results: []
  }
  
  searchGif = (event) => {
    // ... code here
    xhr.onreadystatechange = () => {
    // ... code here
        this.setState();
    }
  }
  render() {
    // ...
  }
}

【讨论】:

  • @RajPowar 或者你可以只使用箭头函数来保留this
  • searchGif =(event) =&gt;{ }就不用绑定了
  • 假设你在编译代码时有正确的 Babel 选项
  • 我给你一个迟来的投票,因为这确实帮助我将 React 组件转换为 ES6 语法。
  • 如果函数是从 say './helpers' 导入的,这个答案有什么不同?我无法将上下文绑定到导入的函数,这导致错误“this.setState is not a function”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
  • 2018-04-09
  • 2017-06-16
相关资源
最近更新 更多