我刚开始使用React,正在构建一个通过Youtube API合并视频搜索的应用。我在查询视频API后,尝试在“搜索结果”div中动态呈现视频数据。
这个“搜索结果”div应该呈现一个名为searchResults的JSX数组,它存储为AddSong组件的状态键值对。在组件构造时,这个数组是空的,它应该被填充在axios get请求的.then(function(response){}函数中(在我的搜索函数中)。
在此功能中,我逐项从API响应中提取相关数据。对于每个项目,我将数据格式化为JSX,并将其存储到名为vidComponents的本地数组中。当我调用this.setState({searchResults:vidComponents})时出现问题。 '这个'未定义。确切的错误如下所示:
TypeError:无法读取未定义
的属性'setState'在做了一些研究后,我了解到大多数人因为没有在构造函数中正确地将“this”绑定到相关函数而得到此错误,但对我来说情况并非如此。 'this'在构造函数中绑定到我的搜索函数,如下所示:
this.search = this.search.bind(this)
有谁知道导致此错误的原因是什么?这是我的代码:
import React, { Component } from 'react';
import axios from 'axios';
import { FormGroup, FormControl, Button } from 'react-bootstrap';
import './add-song-component.css';
class AddSong extends React.Component{
constructor(props, context){
super(props, context);
// Must bind this to functions in order for it to be accessible within them
this.handleTextChange = this.handleTextChange.bind(this);
this.search = this.search.bind(this);
// Object containing state variables
this.state = {
searchText: '',
searchResults: [],
nextPageToken: ''
};
}
// Keeps track of the current string in the search bar
handleTextChange(e){
this.setState({ searchText: e.target.value });
}
// Runs a search for 10 youtube videos through youtube's API
search(e){
// Initialize important data for formatting get request url
var api = this.props.apiKey;
var query = this.state.searchText;
var maxResults = 10;
// Execute get request on Youtube's search API
axios.get('https://www.googleapis.com/youtube/v3/search', {
params: {
part: 'snippet',
type: 'video',
order: 'viewCount',
key: api,
q: query,
maxResults: maxResults
}
})
.then(function (response) {
console.log(response.data);
var vidComponents = [];
// Loop through video data, extract relevant info
var i = 0;
for (let vidInfo of response.data.items) {
vidComponents.push(
<div key={i}>
<p>title: {vidInfo.snippet.title}</p>
<p>channel: {vidInfo.snippet.channelTitle}</p>
<p>id: {vidInfo.id.videoId}</p>
<p>thumbnailUrl: {vidInfo.snippet.thumbnails.high.url}</p>
</div>
);
i++;
}
// Set searchResults state to account for new results...
// Set nextPageToken state based on value from youtube's response
// *** used for retrieving more videos from initial query ***
this.setState({
searchResults: vidComponents,
nextPageToken: response.data.nextPageToken
});
})
.catch(function (error) {
console.log(error);
});
}
render(){
return(
<div className="add-song">
<form>
<FormGroup controlId="SearchText">
<FormControl
type="text"
placeholder="Search for a song / video"
value={this.state.searchText}
onChange={this.handleTextChange}
/>
</FormGroup>
<Button onClick={this.search}>Search</Button>
</form>
<div className="search-results">
{this.state.searchResults}
</div>
</div>
);
}
}
export default AddSong;
答案 0 :(得分:1)
恕我直言,您的For Each rw In sheet.Rows
If rw.Cells(1, 1).Value = "<YOUR STRING HERE>" Then
...
Next rw
和search
函数在构造函数中的作用域都很好。那应该不是问题。但我确实在handleSearch
func:
setState
search
如果您可以使用箭头功能,那会更好!
axios.get(...).then(function() { this.setState(...) }
答案 1 :(得分:0)
handleTextChange = e => {
this.setState({ searchText: e.target.value });
}
此语法将this
绑定到当前类。在您的情况下,this
将指向当前的函数范围,因此您将获得undefined
答案 2 :(得分:0)
您缺少this
绑定到handleTextChange
函数的内容。因此,未使用Component this
对象调用它。
解决方案1:在构造函数中使用绑定
constructor(props, context){
super(props, context);
//...
this. handleTextChange = this.handleTextChange.bind(this);
}
解决方案2:使用 arrow function
。
handleTextChange =(e)=>{
this.setState({ searchText: e.target.value });
}