首页 > 解决方案 > 使用 onChange 通过搜索栏过滤 React 组件

问题描述

我有一个反应应用程序,其中多个组件呈现在几个不同的页面上。我构建了一个搜索栏组件,可以在 5 个不同的页面上重复使用和呈现,以过滤每个页面上包含的组件。

我想要实现 的目标:我希望搜索栏在不使用 onClick 按钮的情况下过滤整个组件。它需要以onChange相同的方式过滤整个组件,.filter()并且 onChange 在用户键入时通过文本数组列表过滤,并仅显示匹配关键字的组件并隐藏其余组件。

我试图在当前代码中解决的问题:

  1. 我可以让整个组件进行过滤的唯一方法是通过 SearchBar 组件本身添加和显示它们,但需要通过当前页面组件而不是<Block />在 SearchBar 组件中使用来操作和过滤来显示它们。SearchBar 应该只过滤当前页面上呈现的任何组件。(Block 只是用来测试它是否过滤了整个组件)

  2. 状态中的关键字compList:仅在它们是组件的确切名称时才起作用,但它需要使用诸如["taco", "burrito"]等之类的通用关键字来触发(可能以某种方式将关键字引用到实际组件?)

  3. 出于某种原因,如果用户退格,则所有组件都会<Block />消失。这不需要发生..需要显示所有组件,直到找到匹配项。(不知何故它可能会改变状态 compList ?)

搜索栏组件

import React from 'react';
import './search-bar-styles.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { BreakfastBurritoRecipe, BreakfastTacoRecipe } from './recipe-box';


export class SearchBar extends React.Component {
   
    constructor(props) {
        super(props);
        this.state = { 
            display: 'none',
            value: '',
            compList: ["BreakfastTacoRecipe", "BreakfastBurritoRecipe"]

        };
    
        this.showBar = this.showBar.bind(this);
        this.hideBar = this.hideBar.bind(this);
        this.userText = this.userText.bind(this);
    };


    showBar() {
        this.setState({ display: 'block' });
    };

    hideBar() {
        this.setState({ display: 'none', value: '' });
    };

    userText(event) {

        const newList = this.state.compList.filter(item => item.includes(this.state.value))
        this.setState({ value: event.target.value, compList: newList })        
    }


    render() {

        const _components = {
            BreakfastTacoRecipe,
            BreakfastBurritoRecipe
        }  

        return (
            <div>
                <div id="searchButtonContainer" /*name={this.userText}*/>
                    <div id="searchButton" onClick={this.showBar}>
                        <FontAwesomeIcon icon={faSearch} />
                    </div>
                </div>
                <div id="searchContainer">
                    <div id="searchBox" style={{display: this.state.display}} onChange={this.showBar}>
                        <input value={this.state.value} onChange={this.userText} type="text" placeholder="Search.." />
                        <span id="closeSearchBtn" onClick={this.hideBar}>X</span>
                        <p>{this.state.value}</p>
                        <div>
                            {this.state.compList.map((component, index) => {
                            const Block = _components[component];
                            return <Block key={index} />
                        })}
                        </div>
                    </div>
                </div>
            </div>
        )
    }
};

将呈现 SearchBar 的 5 个页面中的 1 个示例

import React from 'react';
import './breakfast-styles.scss';
import { Header } from './header.js';
import { BreakfastTitleBox } from './breakfast-title-box.js';
import { BreakfastTacoRecipe } from './recipe-box.js';
import { BreakfastBurritoRecipe } from './recipe-box.js';
import { OmeletteRecipe } from './recipe-box.js';
import { BiscuitsNGravyRecipe } from './recipe-box.js';
import { SausageBreakfastRollRecipe } from './recipe-box.js';
import { Footer } from './footer.js';
import ScrollArrow  from './scrolltotop.js';
import { SearchBar } from './search-bar.js';


export class Breakfast extends React.Component {



    render() {
        return (
            <div>
                <ScrollArrow />
                <Header />
                <SearchBar />             <-----SearchBar being rendered on page
                <BreakfastTitleBox />
                <BreakfastTacoRecipe />   <----component to be filtered
                <BreakfastBurritoRecipe />    <----component to be filtered
                <OmeletteRecipe />            <----component to be filtered
                <BiscuitsNGravyRecipe  />     <----component to be filtered
                <SausageBreakfastRollRecipe /> <----component to be filtered
                <Footer />
            </div>
        )
    }
}

有什么建议么?例子?

标签: javascriptreactjsfilteronchangereact-component

解决方案


推荐阅读