我正在尝试创建一个过滤器,按类型和文本过滤对象数组。
期望的结果应该是:如果没有通过过滤器,则显示所有内容;当按文本过滤时,将显示相关的结果(考虑到哪种类型是活动的);当类型是活动的时,将显示按类型的结果,考虑到传递了哪些文本(如果已传递了任何文本)
结果是,当我尝试按文本搜索时,没有任何结果,除非我按类型设置过滤器。
我的过滤器是
async function query(filterBy) {
let melodies = _loadMelodiesFromStorage();
try {
if (!filterBy) return melodies;
if (filterBy.genre === 'none') {
return melodies;
}
const filterRegex = new RegExp(filterBy.text, 'i');
let filteredMelodies = melodies.filter((melody) => {
return filterRegex.test(melody.name);
});
console.log('filteredMelodies:', filteredMelodies);
filteredMelodies = filteredMelodies.filter((melody) => {
return melody.genre === filterBy.genre;
});
return filteredMelodies;
} catch (err) {
console.log('cant get melodies from local storage', err);
throw err;
}
}
这是过滤器组件:
import React, { useState, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { loadMelodies } from '../cmps/store/melody.action.js';
import { melodyService } from '../service/melody.service.js';
const Filters = () => {
const dispatch = useDispatch();
const genres = melodyService.getGenres();
const [filter, setFilter] = useState({
text: null,
genre: 'none',
});
useEffect(() => {
dispatch(loadMelodies(filter));
}, [filter]);
return (
<div className='w-full flex pb-5'>
<input
className='block appearance-none border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline'
type='text'
placeholder='Search...'
value={filter.text}
onChange={(e) => setFilter({ ...filter, text: e.target.value })}
/>
<select
className='block appearance-none border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline'
value={filter.genre}
onChange={(e) => setFilter({ ...filter, genre: e.target.value })}>
{genres.map((genre) => (
<option value={genre.toLowerCase()}>{genre}</option>
))}
</select>
</div>
);
};
export default Filters;
我会尽量简化一下,也许像这样:
const query = ({ genre, text } = {}) => {
let list = melodies //get them somewhat
if (genre) {
list = list.filter(m => m.genre === genre)
}
if (text) {
list = list.filter(m => m.text.includes(text))
}
return list
}
const melodies = [
{ genre: 'g1', text: 'this is my text' },
{ genre: 'g2', text: 'another text' },
{ genre: 'g2', text: 'description' }
]
const query = ({ genre, text } = {}) => {
let list = melodies
if (genre) {
list = list.filter(m => m.genre === genre)
}
if (text) {
list = list.filter(m => m.text.includes(text))
}
return list
}
console.log(query({ text: 'text' }))
console.log(query({ genre: 'g2' }))
console.log(query({ genre: 'g2', text: 'description' }))
console.log(query())
这个条件是否意味着如果您的genre
过滤器设置为'none'
,那么您的query
函数将返回所有没有执行文本过滤器的机会的结果?我建议你把你的query
功能分成几个小的。
if (filterBy.genre === 'none') {
return melodies;
}
我添加了
if (!filterBy || (filterBy.text === '' && filterBy.genre === 'None')) {
return melodies;
}
可能不是最好的解决方案,但它有效。