通过复选框过滤对象数组
问题:通过复选框过滤对象数组 这是一个React.js过滤器问题,我被困在这里。该问题将电影的静态数据作为对象数组,我们必须根据不同复选框的选中状态过滤该数据。 静态数据: export const data = [ { id: 1, title: 'Batman', rating: 1, genre: 'Action' }, { id: 2, title: 'Superman', rating:
问题:通过复选框过滤对象数组
这是一个React.js
过滤器问题,我被困在这里。该问题将电影的静态数据作为对象数组,我们必须根据不同复选框的选中状态过滤该数据。
静态数据:
export const data = [
{
id: 1,
title: 'Batman',
rating: 1,
genre: 'Action'
},
{
id: 2,
title: 'Superman',
rating: 5,
genre: 'Comedy'
},
{
id: 3,
title: 'Spiderman',
rating: 3,
genre: 'Thriller'
},
{
id: 4,
title: 'BananaMan',
rating: 2,
genre: 'Action'
},
{
id: 5,
title: 'OrangeMan',
rating: 4,
genre: 'Drama'
}
];
抽象的 UI 有以下图片,代表 2 种类型的过滤器。
-
评分
-
类型
截屏:
两个过滤器都在 UI 上呈现为复选框。所以,我创建了一个名为Checkboxes
的组件,它将采用一个名为list
的道具,它是一个对象数组。
这个list
代表唯一的ids
复选框,这将帮助我们跟踪复选框的checked
或unchecked
状态。不同的复选框id
将保存在一个数组的状态中。
const [checkedArray, setCheckedArray] = useState([]);
最后,我在名为App.js
的父组件内渲染了这个Checkboxes
组件两次。一个用于评级,另一个用于流派。
列表:
export const listCheckboxesRating = [
{
id: 0,
name: 'rating',
label: 'Any Rating'
},
{
id: 1,
name: 'rating1',
label: 'Rating 1'
},
{
id: 2,
name: 'rating2',
label: 'Rating 2'
},
{
id: 3,
name: 'rating3',
label: 'Rating 3'
},
{
id: 4,
name: 'rating4',
label: 'Rating 4'
},
{
id: 5,
name: 'rating5',
label: 'Rating 5'
}
];
export const listCheckboxesGenre = [
{
id: 0,
name: 'genre',
label: 'Any Genre'
},
{
id: 1,
name: 'action',
label: 'Action'
},
{
id: 2,
name: 'comedy',
label: 'Comedy'
},
{
id: 3,
name: 'drama',
label: 'Drama'
},
{
id: 4,
name: 'thriller',
label: 'Thriller'
}
];
复选框组件:
import {useState} from 'react';
import {handleToggle} from '../../utils';
const Checkboxes = ({list, handleFilters}) => {
const [checkedArray, setCheckedArray] = useState([]);
const onChangeHandler = (checkboxId) => {
const newState = handleToggle(checkboxId, checkedArray);
setCheckedArray(newState);
// Update this checked information into Parent Component
handleFilters(newState);
};
return list.map((item, index) => {
return (
<div key={index}>
<input
type="checkbox"
id={item.name}
checked={checkedArray.indexOf(item.id) !== -1}
onChange={() => onChangeHandler(item.id)}
/>
<label htmlFor={item.name}>{item.label}</label>
</div>
);
});
};
export default Checkboxes;
我通过名为handleFilters
的函数将这些复选框的整个状态传递给父组件App.js
。你可以看到这行代码。
handleFilters(newState);
App.js
组件正在保存这些复选框的状态,如下所示:
const [selected, setSelected] = useState({
rating: [],
genre: []
});
App.js 组件:
import {useState} from 'react';
import Checkboxes from './Checkboxes';
import {data, listCheckboxesRating, listCheckboxesGenre} from '../data';
const App = () => {
const [movies, setMovies] = useState(data);
const [selected, setSelected] = useState({
rating: [],
genre: []
});
/**
* This function will perform the filtration process based on the key value.
*
* @param {number[]} checkboxState - It will take the final state of checkboxes
* @param {string} key - It will help us to determine the type of filtration
*/
const handleFilters = (checkboxState, key) => {
const newFilters = {...selected};
newFilters[key] = checkboxState;
// Filtration process
for (let key in newFilters) {
if (
newFilters.hasOwnProperty(key) &&
Array.isArray(newFilters[key]) &&
newFilters[key].length > 0
) {
if (key === 'rating') {
} else if (key === 'genre') {
}
}
}
// Save the filtered movies and update the state.
// setMovies();
setSelected(newFilters);
};
return (
<div>
{movies.map((movie) => (
<div key={movie.id}>
<div>Name: {movie.title}</div>
<div>Genre :{movie.genre}</div>
<div>Rating: {movie.rating}</div>
<hr />
</div>
))}
<div className="row">
<div className="col">
<h1>Filter by Rating</h1>
<Checkboxes
list={listCheckboxesRating}
handleFilters={(checkboxState) =>
handleFilters(checkboxState, 'rating')
}
/>
</div>
<div className="col">
<h1>Filter by Genre</h1>
<Checkboxes
list={listCheckboxesGenre}
handleFilters={(checkboxState) =>
handleFilters(checkboxState, 'genre')
}
/>
</div>
</div>
</div>
);
};
export default App;
两个过滤器的复选框checked
或unchecked
状态工作正常,并且在父selected
状态内使用ids
正确更新,如下所示。
const [selected, setSelected] = useState({
rating: [1,2,3],
genre: [2,4]
});
但这是我卡住的令人困惑的部分。如何映射这些复选框ids
并根据这些ids
过滤数据?
我在App.js
组件handleFilters(checkboxState, key)
中定义了一个函数,我想在其中迭代selected
状态以执行过滤过程,但我的头脑没有逻辑,我需要帮助。
工作演示:
存储库链接。
解答
我做了一些重构。
- 使数据更通用。
export const listCheckboxesRating = {
key: 'rating',
data: [
{
id: 1,
name: 'rating1',
label: 'Rating 1',
value: 1
},
...
}
- 重构 Checkbox 组件,只传递数据。
<Checkboxes
list={listCheckboxesGenre}
handleFilters={handleFilters}
/>
3.使过滤过程具有价值和关键。
// Filtration process
let filteredMovies = data.filter((movie) => {
for (let key in newFilters) {
if (
newFilters.hasOwnProperty(key) &&
Array.isArray(newFilters[key]) &&
newFilters[key].length > 0
) {
if (
newFilters[key].findIndex((value) => movie[key] === value) === -1
) {
return false;
}
}
}
return true;
});
工作演示:https://codesandbox.io/s/react-filter-forked-gs2b2?fileu003d/src/components/App.js
更多推荐
所有评论(0)