Поиск в списке и фильтрация

Последнее обновление: 23.03.2025

Поиск в списке представляет распространенный пример работы с элементами формы и взаимодействия между компонентами. Поэтому рассмотрим его и для этого определим следующую веб-страницу:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
    import React from "https://esm.sh/react@19?dev";
    import ReactDOM from "https://esm.sh/react-dom@19/client?dev";

    const propsValues = {
        title: "Языки программирования",
        items: [
                "JavaScript", 
                "C++", 
                "TypeScript", 
                "Java", 
                "C#", 
                "Python"
        ]
    };
       
    function SearchPlugin(props){

        function onTextChanged(e){
            const text = e.target.value.trim();   // удаляем пробелы
            props.filter(text); // передаем введенный текст в родительский компонент
        }
                
        return <input placeholder="Поиск" onChange={onTextChanged} />;
    }
                    
    function ItemsList(props){ 
            
        const [items, setItems] = React.useState(props.data.items);
                
        const filterList = (text)=> {
            const filteredList = props.data.items.filter((item) =>
                item.toLowerCase().search(text.toLowerCase())!== -1
            ); 
            setItems(filteredList);
        }
                
        return(
            <div>         
                <h2>{props.data.title}</h2>
                <SearchPlugin filter={filterList} />
                <ul>
                {
                    items.map((item) =>  <li key={item}>{item}</li>)
                }
                </ul>
            </div>
        );
    }
            
    ReactDOM.createRoot(
        document.getElementById("app")
    )
    .render(
        <ItemsList data={propsValues} />
    );
    </script>
</body>
</html>

ПРимер работы:

Передача данных между компонентами в React Фильтрация в списке в React

Прежде всего у нас определен компонент SearchPlugin, который представляет поле поиска:

<input placeholder="Поиск" onChange={onTextChanged} />;

При вводе срабатывает функция onTextChanged, которая получает введенное значение и передает его вверх в функцию props.filter(), которая определена в родительском компоненте:

function onTextChanged(e){
    const text = e.target.value.trim();   // удаляем пробелы
    props.filter(text); // передаем введенный текст в родительский компонент
}

Дополнительно здесь мы могли бы использовать какую-нибудь предобработку, валидацию и т.д., но в данном случае ограничимся удалением пробелов в введенной строке.

Само управление списком происходит в компоненте ItemsList. Он получает данные извне через свойства props. Но при этом компонент выводит в список не те объекты, которые передаются через props.data.items, а объекты из состояния items. В самом начале эти объекты совпадают:

const [items, setItems] = React.useState(props.data.items);

Вывод данных в компоненте:

<ul>
{
    items.map((item) =>  <li key={item}>{item}</li>)
}
</ul>

В компоненте также определена функция фильтрации - filterList:

const filterList = (text)=> {
    const filteredList = props.data.items.filter((item) =>
        item.toLowerCase().search(text.toLowerCase())!== -1
    ); 
    setItems(filteredList);
}

Она получает введенный в текстовое поле текст и на его основе выполняет фильтрацию элементов списка, изменяя состояние - переменную items.

Аналогичный пример на компонентах=классах:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
    import React from "https://esm.sh/react@19?dev";
    import ReactDOM from "https://esm.sh/react-dom@19/client?dev";

    const propsValues = {
        title: "Языки программирования",
        items: [
                "JavaScript", 
                "C++", 
                "TypeScript", 
                "Java", 
                "C#", 
                "Python"
        ]
    };
                
    class Item extends React.Component {
        render() {
            return <li>{this.props.name}</li>;
        }
    }
            
    class SearchPlugin extends React.Component{
                
        constructor(props){
            super(props);
        }
                
        onTextChanged= (e) => {
            const text = e.target.value.trim();   // удаляем пробелы
            this.props.filter(text); // передаем введенный текст в родительский компонент
        }
                
        render() {
            return <input placeholder="Поиск" onChange={this.onTextChanged} />;
        }
    }
                    
    class ItemsList extends React.Component {
        constructor(props){
            super(props);
            this.state = { items: this.props.data.items};
        }
                
        filterList = (text)=> {
            const filteredList = this.props.data.items.filter((item) =>
                item.toLowerCase().search(text.toLowerCase())!== -1
            ); 
            this.setState({items: filteredList});
        }
                
        render() {
            return(
                <div>         
                    <h2>{this.props.data.title}</h2>
                    <SearchPlugin filter={this.filterList} />
                    <ul>
                        {
                            this.state.items.map(function(item){
                                return <Item key={item} name={item} />
                            })
                        }
                    </ul>
                </div>);
        }
    }
            
    ReactDOM.createRoot(
        document.getElementById("app")
    )
    .render(
        <ItemsList data={propsValues} />
    );
    </script>
</body>
</html>
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850