如何过滤这些数据?

How can I filter this data?

我有一个 productSlice 如下:

export const productSlice = createSlice({
  name: 'productSlice',
  initialState: {
    products: [
      {
        id: 0,
        name: 'AutoPart 1',
        desc:
          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
        price: 800,
        picture: IMAGES.aTeamPerfomance12CircuitWires,
        currentQuantity: 1,
        category: 'Wiring',
      },
      ...
    ],
    hasAppliedFilter: false,
    filteredList: [],
    searchResult: [],
    selectedCategory: 0,
    categories: [
      'All',
      'Engine & Emissions',
      'Lamps & Lighting',
      'Brakes & Suspension',
      'Tyres & Rims',
      'Wiring',
      'Electrical',
    ],
  },
  reducers: {
    filterList: (state, action) => {
    },
    searchList: (state, action) => {
    },
  },
});

ProductSection.js 中,我的类别设置如下:

<ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          style={{margin: 10, maxHeight: 40}}>
          {categories.map((item, index) => {
            return (
              <TouchableOpacity
                style={{
                  marginBottom: 5,
                  padding: 2,
                }}
                onPress={() => dispatch(filterList(index))}>
                <Text
                  style={{
                    fontWeight: 'bold',
                    marginRight: 30,
                    opacity: index == selectedCategory ? 1 : 0.2,
                    color: theme.text,
                    ...FONTS.body3,
                  }}>
                  {item}
                </Text>
              </TouchableOpacity>
            );
          })}
        </ScrollView>

我想要实现的是当按下一个类别时,产品将被过滤以仅显示与该类别匹配的产品。但是当category值为'All'时,所有的产品都会显示出来。 filteredList 数组用于根据所选类别过滤的产品,searchResult 用于根据用户输入值过滤的产品。 hasAppliedFilter 应该检查用户是否在过滤,否则显示所有产品。

我假设您想在电子商务应用程序中实现搜索输入和类别选项卡。

第 1 步:

Your Redux state must look like it as per because final products are computable from them (See Thinking in React Step 3 (https://reactjs.org/docs/thinking-in-react.html)) 
- filteredList: [],
+ selectedCategory:string,
- searchResult: [],
+ searchText:string,

第 2 步:在搜索组件中提取状态并过滤它们

import { FC } from 'react'
import { useSelector } from 'react-redux'

export const isEmpty = (param: any) => !param ? true : false
export const isTextContainSearchText = (text: string, searchText: string) => text.indexOf(searchText) > -1

export const isEmptyString = (p: string) => {
    if (isEmpty(p) || p!.trim().length === 0) {
        return true
    } else return false
}


export const filterProducts = (selectedCategory: any, searchText: any, products: any[]) => {
    var r = products;
    if (selectedCategory !== 'All') {
        r = products.filter(({ category }) => category === selectedCategory)
    }

    if (!isEmptyString(searchText)) {
        searchText = searchText.toLowerCase()
        r = r.filter(({ name }) => isTextContainSearchText(name.toLowerCase(), searchText))
    }
    return r
}

const SearchComponent: FC = () => {

    const { selectedCategory, searchText, products } = useSelector(state => state.product)
    const ps = filterProducts(selectedCategory, searchText, products)

    return (
        <div>
            {JSON.stringify(ps)}
        </div>
    )
}

注意:以下是 filterProducts 的一些有趣的测试用例

import { filterProducts } from "."

test('should filterProducts', () => {
    const products = [
        {
            id: 0,
            name: 'AutoPart 1',
            desc:
                'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
            price: 800,
            currentQuantity: 1,
            category: 'Wiring',
        },
    ]
    expect(filterProducts('All', '', products)).toHaveLength(1)
    expect(filterProducts('Wiring', '', products)).toHaveLength(1)
    expect(filterProducts('Electicals', '', products)).toHaveLength(0)
    expect(filterProducts('All', 'ram', products)).toHaveLength(0)
})