gpt4 book ai didi

javascript - 通过复选框过滤对象数组

转载 作者:行者123 更新时间:2023-12-05 00:25:44 26 4
gpt4 key购买 nike

这是 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 种类型的过滤器。
  • 评分
  • 类型

  • 截图:
    Filters screenshot
    两个过滤器都在 UI 上呈现为复选框。所以,我创建了一个名为 Checkboxes 的组件。它将采用名为 list 的 Prop 它是一个对象数组。
    这个 list代表唯一 ids复选框将帮助我们跟踪 checkedunchecked复选框的状态。不同的复选框 id将保存在数组的状态中。
    const [checkedArray, setCheckedArray] = useState([]);
    最后,我正在渲染 Checkboxes父组件内的组件两次称为 App.js .一个用于评级,另一个用于流派。
    名单:
    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;
    复选框 checkedunchecked两个过滤器的状态都工作正常并正确更新为 ids父级内部 selected用这样的东西说明。
     const [selected, setSelected] = useState({
    rating: [1,2,3],
    genre: [2,4]
    });
    但这是我卡住的令人困惑的部分。如何映射这些复选框 ids并根据这些 ids 过滤数据?
    我在 App.js 中定义了一个函数组件 handleFilters(checkboxState, key)我想在其中迭代 selected状态来执行过滤过程,但我的头脑没有逻辑,我需要帮助。
    工作演示:
    Edit react-filter
    repository link .

    最佳答案

    因此,我必须对您的代码进行一些更改才能解决正确的过滤问题:

  • 添加了 value两个键listCheckboxesRatinglistCheckboxesGenre用于过滤。
  • export const listCheckboxesGenre = [
    {
    id: 0,
    name: 'genre',
    label: 'Any Genre',
    value: ''
    },
    ...
    }
  • 更新 onChangeHandler通过value返回 handleFilters而不是 id
  • const onChangeHandler = (checkboxId) => {
    // ...
    handleFilters(newState.map((id) => list[id].value));
    };
  • 创建了几个过滤器功能来过滤电影。
  • const handleFilters = (checkboxState, key) => {
    const newFilters = { ...selected };
    newFilters[key] = checkboxState;

    const hasFilters =
    newFilters.rating.length > 0 || newFilters.genre.length > 0;
    const filterRating = (module) =>
    newFilters.rating.includes(0) ||
    newFilters.rating.includes(module.rating);
    const filterGenre = (module) =>
    newFilters.genre.includes('') || newFilters.genre.includes(module.genre);

    const filteredMovies = data.filter(
    (m) => !hasFilters || filterRating(m) || filterGenre(m)
    );
    setMovies(filteredMovies);
    setSelected(newFilters);
    };

    工作演示:
    Edit react-filter (forked)

    关于javascript - 通过复选框过滤对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67764729/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com