如何创建函数过滤器 reactjs?

IT技术 javascript reactjs ecmascript-6 filter
2021-05-09 06:29:16

下图中是评论布局,我想创建一个过滤器功能。如果客户选择一星过滤器,那么将出现在过滤器下方布局中的只有一颗星,依此类推,如果客户选择有照片,则只显示有照片的评论,反之亦然)

在此处输入图片说明

下面是显示上图的源代码

import React, { useEffect, useState } from 'react';
import RatingCardProductDetail from '../../components/RatingCardProductDetail';
import "./style.sass";
import FilterReviewProductDetail from '../../components/FilterReviewProductDetail';
import { Row, Col, Pagination, Spin } from 'antd';
import LatestReview from '../../components/LatestReview';
import strings from '../../localization/localization';
import Product from '../../repository/Product';

function ReviewProductDetail({ productId }) {
    const [reviewRatingDetail, setReviewRatingDetail] = useState({})
    const [reviewRating, setReviewRating] = useState([])
    const [notFound, setNotFound] = useState(false)
    const [loading, setLoading] = useState(false)
    const [ratingStar, setRatingStar] = useState()

    useEffect(() => {
        getReviewRatingDetail();
        getReviewRating();
        setRatingStar('')
    }, [productId])


    async function getReviewRatingDetail() {
        let reviewRatingDetail = await Product.reviewRatingDetail({
            productId: productId
        })
        if (reviewRatingDetail.status === 200) {
            setReviewRatingDetail(reviewRatingDetail)
        } else {
            setReviewRatingDetail({})
        }
    }

    async function getReviewRating() {
        let reviewRating = await Product.reviewRating({
            productId: productId,
            loading: setLoading
        })
        if (reviewRating.status === 200) {
            setReviewRating(reviewRating)
            setNotFound(false)
        } else {
            setReviewRating([])
            setNotFound(true)
        }
    }

    function actionChangeSelectFilter(e) {
        console.log(e);
        setRatingStar(e)
    }

    const filterReviewRating = reviewRating.review &&
        reviewRating.review.filter(review => {
            return Object.keys(review).some(key =>
                review[key].toString().includes(ratingStar)
            );
        })

    console.log('filterReviewRating', filterReviewRating);

    return (
        <Spin spinning={loading}>
            <div className="mp-review-product-detail">
                {notFound ?
                    <div className="mp-product-detail__not-found">
                        <span>
                            Belum ada ulasan untuk produk ini
                        </span>
                    </div> :
                    <React.Fragment>
                        <RatingCardProductDetail
                            reviewRatingDetail={reviewRatingDetail} />
                        <Row>
                            <Col md={17} offset={3}>
                                <div className="mp-review-product-detail__filter">
                                    <FilterReviewProductDetail
                                        actionChangeSelectFilter={actionChangeSelectFilter} />
                                </div>
                            </Col>
                        </Row>
                        <h3>{strings.latest_review}</h3>
                        {reviewRating.review &&
                            filterReviewRating.map((review, i) => {
                                return <LatestReview key={i} review={review} />
                            })}
                        <Pagination
                            className="mp-pagination-review-product-detail"
                            defaultCurrent={1}
                            total={5} />
                    </React.Fragment>}
            </div>
        </Spin>
    );
};

export default ReviewProductDetail;

这是我用红色标记的过滤器按钮的来源

import React from 'react';
import { Rate, Radio } from 'antd';

function FilterReviewProductDetail({ actionChangeSelectFilter }) {

    const filterReviewMap = [
        {
            name: 'Semua',
            value: ' ',
            icon: ''
        },
        {
            name: 'Dengan Foto',
            value: 'Dengan Foto',
            icon: ''
        },
        {
            name: 'Dengan Deskripsi',
            value: 'Dengan Deskripsi',
            icon: ''
        },
        {
            name: '1',
            value: 1,
            icon: <Rate disabled defaultValue={1} count={1} />
        },
        {
            name: '2',
            value: 2,
            icon: <Rate disabled defaultValue={1} count={1} />
        },
        {
            name: '3',
            value: 3,
            icon: <Rate disabled defaultValue={1} count={1} />
        },
        {
            name: '4',
            value: 4,
            icon: <Rate disabled defaultValue={1} count={1} />
        },
        {
            name: '5',
            value: 5,
            icon: <Rate disabled defaultValue={1} count={1} />
        }
    ]
    return (
        <React.Fragment>
            <span>Filter</span>
            <Radio.Group
                defaultValue={"Semua"}
                size="large"
                onChange={e => actionChangeSelectFilter(e.target.value)}>
                {filterReviewMap.map((review,i) => {
                    return <Radio.Button key={i} value={review.value}>
                        {review.name}{review.icon}
                    </Radio.Button>
                })}
            </Radio.Group>
        </React.Fragment>
    );
};

export default FilterReviewProductDetail;

然后我直接在 Codesanbox 中制作

2个回答

试试这个

您需要修复 filterReviewRating 以过滤适量的星星

原来的

const filterReviewRating = dataDummy.filter(review => {
    return Object.keys(review).some(key =>
      review[key]
        .toString()
        .toLowerCase()
        .includes(ratingStar)
);
});

新的

const filterReviewRating = dataDummy.filter(review => {
    //Check if ratingStar is empty
    if (!ratingStar) 
        return true;
    return review.rating == ratingStar;
});

而且您还需要更改LatestReview/index.js

<Rate disabled defaultValue={rating} />

<Rate disabled value={rating} />

我的方法是使用 state 来存储“star”值。参考useState

const [starFilter, setStarFilter] = useState('all');

一旦您通过按钮更新了状态,您就可以轻松地将类似的内容应用于每个元素。

{filterReviewMap.map((review,i) => {
    return (starFilter=== 'all' || starFilter===review.value) &&
        <Radio.Button key={i} value={review.value}>
            {review.name}{review.icon}
        </Radio.Button>
})}