Как правильно искать в списке в ReactJS - PullRequest
2 голосов
/ 06 марта 2020

Я пытаюсь настроить простую операцию поиска в пользовательском интерфейсе, как показано ниже:

search

У меня есть в общей сложности 70 react-strap карточек и каждая карточка содержит судно с названием, типом и изображением. Я хотел бы найти название судна и выдать карту, связанную с этим судном. Все мои изображения в настоящее время содержатся во внешней базе данных Содержательный . Ниже области интересов:

Проблема заключается в том, что я не знаю, как написать функцию поиска, которая находит определенное c значение списка.

list

Ниже кода:

SideBar. js

<code>import React from 'react';
import Client from '../Contentful';
import SearchVessel from '../components/SearchVessel';

class Sidebar extends React.Component {
    state = {
        ships: [],
    };

    async componentDidMount() {
        let response = await Client.getEntries({
            content_type: 'cards'
        });
        const ships = response.items.map((item) => {
            const {
                name,
                slug,
                type
            } = item.fields;
            return {
                name,
                slug,
                type
            };
        });

        this.setState({
            ships
        });
    }

    getFilteredShips = () => {
        if (!this.props.activeShip) {
            return this.state.ships;
        }
        let targetShip = this.state.ships.filter(
            (ship) => this.props.activeShip.name === ship.name
        );
        let otherShipsArray = this.state.ships.filter((ship) => this.props.activeShip.name !== ship.name);
        return targetShip.concat(otherShipsArray);
    };

    render() {
        return (
            <div className="map-sidebar">
                {this.props.activeShipTypes}

                <SearchVessel />

                <pre>
                    {this.getFilteredShips().map((ship) => {
                        console.log(ship);
                        return (
                            <Card className="mb-2">
                                <CardImg />
                                <CardBody>
                                    <div className="row">
                                        <img
                                            className="image-sizing-primary"
                                            src={ship.companylogo.fields.file.url}
                                            alt="shipImage"
                                        />
                                    </div>
                                    <div>
                                        <img
                                            className="image-sizing-secondary"
                                            src={ship.images.fields.file.url}
                                            alt="shipImage"
                                        />
                                    </div>
                                    <CardTitle>
                                        <h3 className="thick">{ship.name}</h3>
                                    </CardTitle>
                                    <CardSubtitle>{ship.type}</CardSubtitle>
                                    <CardText>
                                        <br />
                                        <h6>Project Details</h6>
                                        <p>For a description of the project view the specification included</p>
                                    </CardText>
                                    <Row style={{ marginTop: '20px' }}>
                                        <div className="buttoncontainer">
                                            <div className="btn btn-cards">
                                                <a
                                                    className="buttonLink"
                                                    download
                                                    href={ship.projectnotes.fields.file.url}
                                                >
                                                    Project Notes
                                                </a>
                                            </div>
                                            <div className="btn btn-cards">
                                                <a className="buttonLink" href={ship.abstract.fields.file.url}>
                                                    Abstract
                                                </a>
                                            </div>
                                        </div>
                                    </Row>
                                </CardBody>
                            </Card>
                        );
                    })}
                
); }} экспортировать боковую панель по умолчанию;

Поиск судов. js

import React, { Component } from 'react';

export default class SearchVessel extends Component {
    render() {
        const { value, handleSubmit, handleChange } = this.props;

        return (
            <React.Fragment>
                <div className="container">
                    <div className="row">
                        <div className="col-10 mx-auto col-md-8 mt-5 text-center">
                            <h4 className="text-slanted text-capitalize">Search for Vessel</h4>
                            <form className="mt-4" onSubmit={handleSubmit}>
                                <label htmlFor="search" className="text-capitalize">
                                    type vessel separated by comma
                                </label>
                                <div className="input-group">
                                    <input
                                        type="text"
                                        name="search"
                                        placeholder="Type name of vessel here"
                                        className="form-control"
                                        value={value}
                                        onChange={handleChange}
                                    />
                                    <div className="input-group-append">
                                        <button type="submit" className="input-group-text bg-primary text-white">
                                            <i className="fas fa-search" />
                                        </button>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </React.Fragment>
        );
    }
}

Что я сделал до сих пор:

1) Я пробовал разные комбинации с функцией фильтра, и я думаю, что я близок. Проблема в том, что когда я выполняю поиск, ничего не происходит, и для того, чтобы найти карту судна, которое я хочу, мне нужно прокрутить вниз, пока я не найду ее.

У меня заканчиваются идеи, и если вы видите что-то, что я не уловил, указывает мне верное направление для решения этой проблемы.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Ты близко! Я бы добавил в ваше состояние поле с именем searchText, а затем создал бы метод для фильтрации на основе этого элемента состояния searchText.

getFilteredShips = () => this.state.ships.filter(s => s.name.includes(this.state.searchText)

Затем просто сопоставьте эти значения, чтобы отобразить карточки, соответствующие тексту поиска , Карты будут обновляться каждый раз, когда обновляется значение searchText.

this.getFilteredShips().map(ship => ..........
0 голосов
/ 06 марта 2020

React славится многоразовым компонентом. Вы будете иметь все данные этих судов в массиве. Вы проведете l oop через массив и визуализируете элементы с компонентом карты. И при поиске указанной карты c вы хотите, чтобы это судно выскочило сверху.

Есть два способа сделать это. it:

Вы должны пройти через массив, найти индекс этого судна и сделать все возможное, чтобы манипулировать вашим массивом и сделать этот элемент наверху и повторно отобразить ваш список.

В качестве альтернативы визуализируйте еще один компонент в верхней части списка ваших судов, когда пользователь нажимает кнопку поиска. Вам просто нужно найти предметный указатель и отобразить его. Таким образом, вам не нужно иметь дело с манипуляциями с массивами. Неважно, если у вас есть 80 или 1000 карт.

Пожалуйста, ознакомьтесь с официальной документацией для методов массива, для нарезки массива и сплайсинга. Надеюсь, это то, что вы ищете. Если вам нужна дополнительная помощь, пожалуйста, прокомментируйте.

...