我有一个<select>
,其中<option>
是动态生成的。此外还有一个<input>
,用户输入的内容与过滤<option>
数字的字符相匹配。因此,如果<input>
为空,则返回完整列表,并会显示一条消息116 Results Found
。当他们输入“head”时,它将更新为8 Results Found
。很常见的事。
我无法弄清楚如何计算。我正在尝试在_.map
中执行i++
然后this.setState({ count: i })
;然而,这基本上限制了浏览器,因为它陷入了无限循环(好吧,它在我强行关闭它之前会产生数千个相同的错误,因为浏览器在计算时被锁定)。
另一个想法是计算<option>
元素的数量,但我无法弄清楚如何实现它。
有什么建议吗?
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
class BasicQuery extends Component {
constructor(props) {
super(props);
this.state = {
term: '',
count: ''
};
}
onInputChange(term) {
this.setState({ term });
}
renderOptionsSelect(term) {
var filterTerm = this.state.term.toLowerCase();
var i = 0;
return _.map(this.props.pos_list, p => {
if (p.pos_code.toLowerCase().match(filterTerm)) {
i++;
return (<option key={p.pos_code} value={p.pos_code}>{p.pos_code}</option>);
}
this.setState({ count: i });
});
}
// render the main element of the container
render() {
return (
<div className='panel panel-default'>
<div className='panel-heading'>
<h4><strong>Basic Query</strong></h4>
</div>
<div className='panel-body'>
<input
className='form-control'
placeholder='Enter Keyword or Position Code'
value={this.state.term}
onChange={event => this.onInputChange(event.target.value)}
/>
<hr />
<h4>Position:</h4>
<select className='form-control'>
<option></option>
{this.renderOptionsSelect()}
</select>
<br />
<h4>Data Cut:</h4>
<select className='form-control' disabled={true} />
</div>
</div>
);
}
}
// map the state in the Redux store to props
function mapStateToProps(state) {
return {
results: state.results.results,
pos_list: state.results.pos_list
}
}
export default connect (mapStateToProps, null)(BasicQuery);
答案 0 :(得分:2)
我愿意:
onInputChange(term) {
const filterTerm = term.toLowerCase();
const filteredItems = this.props.pos_list.filter( p =>
p.pos_code.toLowerCase().match(filterTerm)
)
this.setState({
term,
filteredItems,
count: filteredItems.length
});
}
然后在渲染中:
this.state.filteredItems.map( p =>
<option key={p.pos_code} value={p.pos_code}>{p.pos_code}</option>
)
答案 1 :(得分:1)
在渲染方法中,您可以先调用renderOptionsSelect
,然后获取生成的选项数(因为它是一个数组)并显示它。然后我还会过滤你的选项数组:
renderOptionsSelect(term) {
var filterTerm = this.state.term.toLowerCase();
return this.props.pos_list
.filter(p => p.pos_code.toLowerCase().match(filterTerm))
.map(p => (<option key={p.pos_code} value={p.pos_code}>{p.pos_code}</option>));
}
render() {
const options = this.renderOptionsSelect();
const numberOfResults = options.length;
return (
<div className='panel panel-default'>
<div className='panel-heading'>
<h4><strong>Basic Query</strong></h4>
<p>{numberOfResults} Results Found</p>
</div>
<div className='panel-body'>
<input
className='form-control'
placeholder='Enter Keyword or Position Code'
value={this.state.term}
onChange={event => this.onInputChange(event.target.value)}
/>
<hr />
<h4>Position:</h4>
<select className='form-control'>
<option></option>
{options}
</select>
</div>
</div>
);
}
答案 2 :(得分:-1)
无限循环是因为您在render renderOptionsSelect方法中调用setState,该方法在render方法中调用。
你不能在render方法中调用setState,它应该发出警告。
要解决您的问题,您可以计算onInputChange方法中的项目数。