#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;
});