尝试计算<option>,因为它在React应用程序中被过滤掉了

时间:2018-01-12 21:09:21

标签: javascript reactjs react-redux

我有一个<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);

3 个答案:

答案 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方法中的项目数。