我是React的新手。我试图将一个简单的应用程序与三个组件组合在一起 - 一个父组件(SearchContainer)和两个子组件(SearchForm和ResultsContainer)。想法是在搜索表单上输入以使用搜索查询更新SearchForm的状态。然后有一个onSubmit函数用于触发AJAX请求的表单,该请求接受查询,命中API并检索搜索结果。现在,onSubmit函数在页面加载后立即触发,并继续反复触发。我无法弄清楚为什么会这样。这是代码:
SearchContainer(父组件):
var React = require('react');
var ResultsContainer = require('./ResultsContainer.jsx')
var SearchForm = require('./SearchForm.jsx')
var SearchContainer = React.createClass({
getInitialState: function () {
return {
results: null,
formAction: 'http://localhost:3000/search',
formMethod: 'get',
};
},
executeSearch: function(query) {
console.log("executing search");
var data = {
query: query,
};
$.ajax({
url: this.state.formAction,
data: data,
dataType: 'json',
success: this.successFunction,
error: this.errorFunction,
});
},
handleSearch: function(query) {
this.executeSearch(query);
},
successFunction: function(response){
console.log("success");
this.setState({results: response["results"]});
},
errorFunction: function(){
console.log("error");
},
render: function () {
return (
<div className='center-text'>
<SearchForm formAction={this.state.formAction} formMethod={this.state.formMethod} handleSearch={this.handleSearch}/>
<ResultsContainer results={this.state.results}/>
</div>
);
},
});
module.exports = SearchContainer;
SearchForm(孩子):
var React = require('react');
var ResultsContainer = require('./ResultsContainer.jsx')
var SearchForm = React.createClass ({
getInitialState: function () {
return {
query: "",
};
},
handleChange: function(event) {
this.setState({query: event.target.value});
},
render: function () {
return (
<div>
<form onSubmit={this.props.handleSearch(this.state.query)} >
<input className="query" type="text" placeholder="Search..." onChange={this.handleChange}></input>
<input type="submit" value="Search" ></input>
</form>
</div>
);
},
});
module.exports = SearchForm;
导致handleSearch函数一次又一次地触发的原因是什么?谢谢你的帮助。
答案 0 :(得分:5)
您在React中放置花括号{...}的任何内容都将被视为JavaScript表达式,当然在render()
方法运行时运行。
<form onSubmit={console.log('sorry, I am fired on page load! ') }></form>
logToConsole() {
console.log('I will be logged once form is submitted :)');
}
render(
return (<form onSubmit={this.logToConsole}></form>)
)
```
当然,您需要传递给事件处理程序的是一个将在事件触发时触发的函数。
handleSubmit(e) {
e.preventDefault(); // prevent native submitting behavior
// do anything on submit, here!
}
render() {
return(
<form onSubmit={this.handleSubmit}>
......
</form>
)
}
您可以如上所述定义自定义事件处理程序,也可以使用箭头函数来内联完成作业。 有关数组函数的更多信息,请参阅:http://exploringjs.com/es6/ch_arrow-functions.html
render() {
return(
<form onSubmit={(e) => {e.preventDefault(); /* DO SOMETHING HERE */}}>
......
</form>
)
}
答案 1 :(得分:4)
试试这个。
替换
{this.props.handleSearch(this.state.query)}
使用
{this.props.handleSearch.bind(null,this.state.query)}
所以表格现在是
<form onSubmit={this.props.handleSearch.bind(null,this.state.query)} >
<input className="query" type="text" placeholder="Search..." onChange={this.handleChange}></input>
<input type="submit" value="Search" ></input>
</form>
<强>原因:强>
在您的代码中,您实际上是在不触发提交事件的情况下调用onSubmit函数。在新代码中,您只是将函数绑定到事件。事件实际触发时会调用它。
修改强>
如果您还需要事件对象,则要防止默认。
handleSearch: function(query,event) {
console.log(event);
event.preventDefault();
this.executeSearch(query);
}
答案 2 :(得分:0)
此行在渲染表单时调用该函数。
<form onSubmit={this.props.handleSearch(this.state.query)}>
要解决此问题,请不要放置()
,而是从提交处理程序中访问this.state.query
。 React将执行它在每个render
传递中找到的任何函数。
handleSearch (event) {
event.preventDefault();
this.props.handleSearch(this.state.query);
}
然后你的表格看起来像这样
<form onSubmit={this.handleSearch}>
答案 3 :(得分:0)
这是因为您正在调用搜索功能:
this.props.handleSearch(this.state.query)
render
方法在页面加载时运行,并将调用您告诉它的任何函数。
您可能想要执行类似
的操作handleSearch( event ) {
event.preventDefault();
this.props.handleSearch(this.state.query);
},
render() {
...
onSubmit={this.handleSearch}