'this' 在 renderMenuItemChildren 中未定义
'this' undefined in renderMenuItemChildren
我正在使用 react-bootstrap-typeahead asynchronous searching。在 renderMenuItemChildren
方法中,我想调用另一个方法 handleSubmit
来获取所选项目的详细信息。
this
在 renderMenuItemChildren
中未定义,我无法调用该方法。感谢任何帮助。
P.S。我仍在学习 React,因此可能存在我无法识别的愚蠢错误。
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchTitle: '',
defaultUrl: 'http://www.omdbapi.com/?t=arrival'
};
this.handleSearch = this.handleSearch.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.fetchApiData = this.fetchApiData.bind(this);
}
componentDidMount() {
this.fetchApiData(this.state.defaultUrl);
}
fetchApiData(url){
fetch(url)
.then((result) => {
return result.json()
})
.then((json) => {
if(json.Response === "True"){
this.setState({
title: json.Title,
year: json.Year,
released: json.Released,
runtime: json.Runtime,
genreList: json.Genre,
actors: json.Actors,
plot: json.Plot,
poster_url: json.Poster,
rating: json.imdbRating,
boxOffice: json.BoxOffice,
votes: json.imdbVotes,
response: json.Response
});
}
else {
this.setState({
response: json.Response,
error: json.Error
});
}
})
.catch((err) => {
console.log(err);
})
}
handleSubmit(query){
if (!query) {
return;
}
this.fetchApiData(`http://www.omdbapi.com/?t=${query}`);
}
handleSearch(query) {
if (!query) {
return;
}
fetch(`http://www.omdbapi.com/?s=${query}`)
.then((result) => {
return result.json()
})
.then((json) => {
//console.log(json.Search);
this.setState({
options: json.Search
})
});
}
renderMenuItemChildren(option, props, index) {
return (
<div key={option.imdbID} onClick={() =>
this.handleSubmit.bind(option.Title)}>
<span>{option.Title}</span>
</div>
);
}
render() {
return (
<div className="row">
<div className="col-xs-12 col-lg-10 col-lg-offset-1">
<div className="App-header col-xs-12">
<div className="row">
<div className="col-xs-12 col-sm-6 col-lg-5">
<h1><a href="http://www.omdbapi.com/" className="omdb-link" title="The Open Movie Database">OMDb</a></h1>
</div>
<div className="col-xs-12 col-sm-6 col-lg-7">
<AsyncTypeahead
ref="typeahead"
{...this.state}
labelKey="Title"
onSearch={this.handleSearch}
options={this.state.options}
placeholder='Search Title'
className="search-input-box"
renderMenuItemChildren={this.renderMenuItemChildren}
/>
</div>
</div>
</div>
<SearchBody data={this.state} />
</div>
</div>
);
}
}
您还需要在构造函数中绑定函数renderMenuItemChildren
:
添加这个:
this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
这是一个不错的小博客 post,其中有几种方法:Blog Post
那就是说我更喜欢 lodash 的 bindAll:
_.bindAll(this, function1, function2, function3)
您需要在构造函数中执行您为其他方法(handleSearch
、handleSubmit
等)所做的操作:
this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
(或其他几种方式,但这是您用于其他方法的方式,所以...)
这里不需要=>函数。您可以使用以下代码将标题值传回 handleSubmit()
renderMenuItemChildren(option, props, index) {
return (
<div key={option.imdbID} onClick={this.handleSubmit.bind(this, option.Title)}>
<span>{option.Title}</span>
</div>
);
}
虽然 renderMenuItemChildren.bind(this)
在构造函数中肯定有效,但 es6 classes 还允许您使用 箭头函数表达式 作为 class 方法。这将自动将 this
(或者换句话说,上下文)绑定到该方法,减少样板代码的数量,并使您的组件更易于阅读。
所以你的代码可能是这样的:
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchTitle: '',
defaultUrl: 'http://www.omdbapi.com/?t=arrival'
};
}
// etc...
renderMenuItemChildren = () => {
// do stuff
}
}
我正在使用 react-bootstrap-typeahead asynchronous searching。在 renderMenuItemChildren
方法中,我想调用另一个方法 handleSubmit
来获取所选项目的详细信息。
this
在 renderMenuItemChildren
中未定义,我无法调用该方法。感谢任何帮助。
P.S。我仍在学习 React,因此可能存在我无法识别的愚蠢错误。
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchTitle: '',
defaultUrl: 'http://www.omdbapi.com/?t=arrival'
};
this.handleSearch = this.handleSearch.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.fetchApiData = this.fetchApiData.bind(this);
}
componentDidMount() {
this.fetchApiData(this.state.defaultUrl);
}
fetchApiData(url){
fetch(url)
.then((result) => {
return result.json()
})
.then((json) => {
if(json.Response === "True"){
this.setState({
title: json.Title,
year: json.Year,
released: json.Released,
runtime: json.Runtime,
genreList: json.Genre,
actors: json.Actors,
plot: json.Plot,
poster_url: json.Poster,
rating: json.imdbRating,
boxOffice: json.BoxOffice,
votes: json.imdbVotes,
response: json.Response
});
}
else {
this.setState({
response: json.Response,
error: json.Error
});
}
})
.catch((err) => {
console.log(err);
})
}
handleSubmit(query){
if (!query) {
return;
}
this.fetchApiData(`http://www.omdbapi.com/?t=${query}`);
}
handleSearch(query) {
if (!query) {
return;
}
fetch(`http://www.omdbapi.com/?s=${query}`)
.then((result) => {
return result.json()
})
.then((json) => {
//console.log(json.Search);
this.setState({
options: json.Search
})
});
}
renderMenuItemChildren(option, props, index) {
return (
<div key={option.imdbID} onClick={() =>
this.handleSubmit.bind(option.Title)}>
<span>{option.Title}</span>
</div>
);
}
render() {
return (
<div className="row">
<div className="col-xs-12 col-lg-10 col-lg-offset-1">
<div className="App-header col-xs-12">
<div className="row">
<div className="col-xs-12 col-sm-6 col-lg-5">
<h1><a href="http://www.omdbapi.com/" className="omdb-link" title="The Open Movie Database">OMDb</a></h1>
</div>
<div className="col-xs-12 col-sm-6 col-lg-7">
<AsyncTypeahead
ref="typeahead"
{...this.state}
labelKey="Title"
onSearch={this.handleSearch}
options={this.state.options}
placeholder='Search Title'
className="search-input-box"
renderMenuItemChildren={this.renderMenuItemChildren}
/>
</div>
</div>
</div>
<SearchBody data={this.state} />
</div>
</div>
);
}
}
您还需要在构造函数中绑定函数renderMenuItemChildren
:
添加这个:
this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
这是一个不错的小博客 post,其中有几种方法:Blog Post 那就是说我更喜欢 lodash 的 bindAll:
_.bindAll(this, function1, function2, function3)
您需要在构造函数中执行您为其他方法(handleSearch
、handleSubmit
等)所做的操作:
this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
(或其他几种方式,但这是您用于其他方法的方式,所以...)
这里不需要=>函数。您可以使用以下代码将标题值传回 handleSubmit()
renderMenuItemChildren(option, props, index) {
return (
<div key={option.imdbID} onClick={this.handleSubmit.bind(this, option.Title)}>
<span>{option.Title}</span>
</div>
);
}
虽然 renderMenuItemChildren.bind(this)
在构造函数中肯定有效,但 es6 classes 还允许您使用 箭头函数表达式 作为 class 方法。这将自动将 this
(或者换句话说,上下文)绑定到该方法,减少样板代码的数量,并使您的组件更易于阅读。
所以你的代码可能是这样的:
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchTitle: '',
defaultUrl: 'http://www.omdbapi.com/?t=arrival'
};
}
// etc...
renderMenuItemChildren = () => {
// do stuff
}
}