ReactJS中对象数组的搜索与遍历实现技术问询
Here's a step-by-step guide to adding search functionality and rendering your filtered data array in the component:
Step 1: Add State to Track Search Input
First, initialize a state variable in the constructor to keep track of the user's search query:
constructor(props) { super(props); this.state = { searchQuery: '' }; }
Step 2: Handle Search Input Changes
Create a handler function to update the state whenever the user types in the search box. We'll normalize the input to lowercase for case-insensitive searching:
handleSearchChange = (e) => { this.setState({ searchQuery: e.target.value.toLowerCase() }); };
Step 3: Filter the Data Array
Build a helper function to filter your data based on the search query. We'll also exclude items marked as deleted (you can skip this if you want to include deleted entries):
getFilteredData = () => { const { searchQuery } = this.state; // Adjust this to match where your data lives in your Dva model (e.g., this.props.rule.data) const originalData = this.props.rule.data || [ // Fallback sample data if props aren't loaded yet { "id": "1234", "is_deleted": false, "name": "Sarah" }, { "id": "3520", "is_deleted": true, "name": "Bobby" }, { "id": "3520", "is_deleted": true, "name": "Sartah" } ]; return originalData.filter(item => { // Skip deleted items if (item.is_deleted) return false; // Match search query against the item's name (case-insensitive) return item.name.toLowerCase().includes(searchQuery); }); };
Step 4: Update the Render Method
Modify the render method to include the search input and render the filtered results. We'll add a fallback message for empty results and fix the duplicate ID issue in your sample data:
render() { const filteredData = this.getFilteredData(); return ( <div> <Search placeholder="Search by name" value={this.state.searchQuery} onChange={this.handleSearchChange} style={{ width: 300, marginBottom: 16 }} /> {filteredData.length === 0 ? ( <p>No matching results found</p> ) : ( <ul> {filteredData.map(item => ( // Use a combined key to avoid duplicate ID errors <li key={`${item.id}-${item.name}`}> {item.name} (ID: {item.id}) </li> ))} </ul> )} </div> ); }
Key Notes to Keep in Mind
- Case Insensitivity: Converting both the search query and item names to lowercase ensures the search works regardless of how the user capitalizes their input.
- Duplicate IDs: Your sample data has duplicate IDs ("3520")—using a combined key (ID + name) fixes React's rendering warnings, but you should ideally resolve duplicate IDs in your data source.
- Loading State: Since you're using Dva's loading state, you can add a loading indicator easily:
render() { const { loading } = this.props; const filteredData = this.getFilteredData(); if (loading) { return <div>Loading data...</div>; } // Rest of the render code goes here }
Full Updated Component Code
Here's the complete component with all the above changes:
import React from 'react'; import { Input } from 'antd'; import { connect } from 'dva'; const Search = Input.Search; @connect(({ rule, loading }) => ({ rule, loading: loading.models.rule, })) export default class SearchBox extends React.Component { constructor(props) { super(props); this.state = { searchQuery: '' }; } handleSearchChange = (e) => { this.setState({ searchQuery: e.target.value.toLowerCase() }); }; getFilteredData = () => { const { searchQuery } = this.state; const originalData = this.props.rule.data || [ { "id": "1234", "is_deleted": false, "name": "Sarah" }, { "id": "3520", "is_deleted": true, "name": "Bobby" }, { "id": "3520", "is_deleted": true, "name": "Sartah" } ]; return originalData.filter(item => { if (item.is_deleted) return false; return item.name.toLowerCase().includes(searchQuery); }); }; render() { const { loading } = this.props; const filteredData = this.getFilteredData(); if (loading) { return <div>Loading data...</div>; } return ( <div> <Search placeholder="Search by name" value={this.state.searchQuery} onChange={this.handleSearchChange} style={{ width: 300, marginBottom: 16 }} /> {filteredData.length === 0 ? ( <p>No matching results found</p> ) : ( <ul> {filteredData.map(item => ( <li key={`${item.id}-${item.name}`}> {item.name} (ID: {item.id}) </li> ))} </ul> )} </div> ); } }
内容的提问来源于stack exchange,提问作者mokiliii Lo

