Реагирующий фильтр не фильтрует через объекты

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я новичок в react, и у меня проблема с отображением некоторых отфильтрованных данных в компоненте.

У меня есть данные, которые импортируются в состояние родительского <app/> контейнера следующим образом:

 getInitialState () {
    return {
        samples:allSamples,
        searchInputVal:""
    }   
},
  

Вот данные, которые загружаются в исходное состояние образцов:

 export default [
            {
            id:"1",
            sampleName:'Deep House Base',
            sampleFamily:'Deep House Pack',
            parentCategory:"bass",
            subCategory:"house bass",
            uploader:"Ben",
            soundSource:"../../samplesWav/bd_909dwsd.wav",
            tags:[
                "house","ghouse","tech-house","rad"
            ]
        },
            {
            id:"2",
            sampleName:'Deep House Base',
            sampleFamily:'G House Pack',
            parentCategory:"bass",
            subCategory:"house bass",
            uploader:"Ben",
            soundSource:"../../samplesWav/bd_chicago.wav",
            tags:[
                "house","ghouse","tech-house","rad"
            ]
        }
]
  

Я создал компонент заголовка, который является дочерним для <app/> , с вводом на сервер в качестве функции фильтра, например:

 <input placeholder="Search Samples Here..." onChange={this.props.updateSearch} value={this.props.searchInputVal} type="text"></input>
  

При обмене он выполняет функцию updateSearch в своем родительском элементе. Вот как выглядит эта функция:

 updateSearch(event){
    this.setState({
        searchInputVal:event.target.value.substr(0,20)
    })
},
  

В настоящее время, когда я набираю буквы во входных данных, состояние обновляется значением, так что эта часть работает нормально. Это та часть, где я визуализирую свои объекты, которые не фильтруются. Вот компонент, который я пытаюсь отфильтровать:

 class SamplesInnerLrg extends Component {  
    render() {
        let filteredSamples = this.props.loadAllInitSamples.filter(
            (sample) => {
                return sample.sampleFamily.indexOf(
                    this.props.searchInputVal
                )
            }
        )
        return <div className="samples-container-inner-styling">
        {
        console.log(filteredSamples),
        filteredSamples.map((sample) => {
        return (
                <div key={sample.id} className="sample-comp-lge">
                <div className="sample-comp-lge-head-wrap">
                    <div className="sample-comp-lge-audio" id={sample.id} ref={sample.id} onClick={this.playSampleAction.bind(undefined,sample,sample.id)}>
                        <audio preload="auto" className="audioTag">
                              <source src={sample.soundSource} type="audio/wav" />
                        </audio>
                    </div>
                    <div className="sample-comp-lge-header">
                        <span className="sample-comp-lge-Name"><h1>{sample.sampleName}</h1></span>
                        <span className="sample-comp-lge-id"><h2><a href="#">{sample.sampleFamily}</a></h2></span>
                        <div className="sample-comp-lge-owner-cont">
                            <div className="sample-comp-lge-owner-inner">
                                <a href="">{sample.uploader}</a>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="sample-comp-lge-bottom-wrap">
                    <div className="sample-comp-lge-tags-cont">
                        <div className="sample-comp-lge-tag">
                            <ul className="sample-tags-list">
                                {
                                    sample.tags.map((tag) => {
                                        return ( 

                                            <li key={tag}><a href="#">#{tag}</a></li>
                                        )
                                    })

                                }
                            </ul>
                        </div>
                    </div>
                </div>

                </div>
            )
        })
   }
   </div>
    }
}
  

Здесь есть две проблемы с моим рендерингом этого компонента. Прежде всего, когда я загружаю страницу, в DOM не отображаются объекты, но когда я начинаю вводить текст в поле ввода, они внезапно появляются. Во-вторых, не имеет значения, что я набираю, все они будут отображаться независимо от того, что (у меня больше 2, но ради StackOverflow я включил только 2). Где я ошибся?

Ответ №1:

Эта строка:

 let filteredSamples = this.props.loadAllInitSamples.filter(
        (sample) => {
            return sample.sampleFamily.indexOf(
                this.props.searchInputVal
            )
        }
)
  

…проблематично. indexOf возвращает индекс или -1 , если ничего не найдено. .filter(...) ожидает, что функция вернет логическое значение. Вы захотите добавить >= 0 к своему результату индекса, чтобы преобразовать его в логическое значение (при условии, что вы хотите, чтобы «присутствует» было true ):

 const filteredSamples = this.props.loadAllInitSamples.filter(sample => {
  return sample.sampleFamily.indexOf(this.props.searchInputVal) >= 0;
});