You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用中获取筛选后<option>元素数量的实现问题

Hey there! Let's get that result count working properly for your filtered select component—your infinite loop issue makes total sense once we break down what's happening.

What's Causing the Infinite Loop?

The problem with your current code is that you're calling this.setState({ count: i }) inside the _.map loop during the render process. Every time you trigger setState, React re-renders your component, which runs renderOptionsSelect again, which calls setState again... and you end up stuck in an endless cycle. On top of that, you're updating state while iterating through items, which is never a safe practice in React.

The Fix: Filter First, Count Second

Instead of trying to increment a counter while rendering, let's separate our data logic from our UI rendering. Here's the cleaner, React-friendly approach:

  • First, filter your pos_list to get only the items that match the search term
  • The length of this filtered array is exactly your result count—no manual incrementing needed!
  • Then, render the filtered options directly

Updated Component Code

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: '' }; // We don't need to store count in state—it's a derived value!
  }

  onInputChange(term) {
    this.setState({ term });
  }

  render() {
    // Step 1: Get the lowercase filter term once
    const filterTerm = this.state.term.toLowerCase();
    // Step 2: Filter positions to match the term
    const filteredPositions = this.props.pos_list.filter(p => 
      p.pos_code.toLowerCase().includes(filterTerm) // Simpler than match() for basic substring checks
    );
    // Step 3: Count is just the length of the filtered array
    const resultCount = filteredPositions.length;

    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)} 
          />
          {/* Display the result count here */}
          <p>找到{resultCount}条结果</p>
          <hr />
          <h4>Position:</h4>
          <select className='form-control'>
            <option></option>
            {/* Render only filtered positions */}
            {filteredPositions.map(p => (
              <option key={p.pos_code} value={p.pos_code}>
                {p.pos_code}
              </option>
            ))}
          </select>
          <br />
          <h4>Data Cut:</h4>
          <select className='form-control' disabled={true} />
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { results: state.results.results, pos_list: state.results.pos_list }
}

export default connect(mapStateToProps, null)(BasicQuery);

Key Improvements Explained

  • Removed count from state: We don't need to store the count because we can compute it on every render using the current search term and pos_list—this is a "derived value" that doesn't belong in state.
  • Filter before mapping: Filtering the array once gives us all matching items, and mapping over that filtered array is more efficient and cleaner than conditionally rendering inside a loop.
  • Avoided DOM queries: Your idea of counting <option> elements works, but it's not the React way. We should always derive UI state from our data instead of querying the DOM—it's less error-prone and aligns with React's data-driven principles.

This approach will fix your infinite loop, give you accurate result counts every time, and keep your code more maintainable.

内容的提问来源于stack exchange,提问作者strumpy_strudel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:12:39