在React中按多个项目过滤

时间:2017-07-04 12:17:28

标签: javascript reactjs

我想通过将state.items中的项添加到state.filterItems数组

来过滤state.filter中的项目列表

如果我使用this.state.items.filter(items => items.cat === 'veg' )当然这有效但我需要能够使用添加到我的state.filter数组的项目列表动态过滤,我不知道如何做到这一点,< / p>

我还希望能够选择多个选项,然后按一个按钮来应用过滤器,而不是逐个选择它们

https://www.webpackbin.com/bins/-KoCT_DiT2CNLz8ddr4O

Hello.js

import React, { Component } from 'react';
import logo from './logo.svg'
import './App.css'
import update from 'immutability-helper'
import TodoList from './TodoList'
import styled from 'styled-components'
import FilterList from './FilterList'

const Wrapper = styled.div`
  max-width:1280px;
  background: papayawhip;
  margin: 0 auto;
  padding:20px;
`

const Grid = styled.div`
  display:flex;
  flex-wrap:wrap;
`

const Cell = styled.div`
  flex: 0 0 25%;
  padding: 20px;
`

export default class hello extends Component {
  constructor(props) {
    super(props)
    this.state = {
      items: [
        {id: 1, cat: 'fruit', text: 'apples'},
        {id: 2, cat: 'fruit', text: 'oranges'},
        {id: 3, cat: 'fruit', text: 'peaches'},
        {id: 4, cat: 'veg', text: 'carrots'},
        {id: 5, cat: 'veg', text: 'aubergine'},
        {id: 6, cat: 'veg', text: 'peaches'},
        {id: 7, cat: 'bread', text: 'olive bread'},
        {id: 8, cat: 'bread', text: 'bread roll'},
        {id: 9, cat: 'bread', text: 'bagel'},
      ],
      filterItems: [
        {id: 1, text: 'bread'},
        {id: 2, text: 'fruit'},
        {id: 3, text: 'vegetables'},
      ],
      filter: [
        {text: 'bread'}
      ],
    }
  }

  handleFilterChange = (filter) => {
    this.setState({filter: filter})
  }

  render() {
    return (
      <Wrapper>
        <div>
        <FilterList
          value={this.state.filter}
          onChange={this.handleFilterChange}
          filterItems={this.state.filterItems}
        />
        </div>
        <Grid>
          {
            this.state.items.filter(items => items.cat === 'veg', 'fruit' )
            .map(item =>
              <Cell>
                {console.log(this.state.filter.text)}
                <div>{item.cat}</div>
                <div>{item.text}</div>
              </Cell>
            )
          }
        </Grid>
      </Wrapper>
    )
  }
}

//  <pre>{JSON.stringify(this.state, null, 4)} </pre>

FilterList.js

import React, { Component } from 'react';
import TodoItem from './TodoItem'
import update from 'immutability-helper'
import styled from 'styled-components'

const FilterListBg = styled.div`
  background: lightblue;
  width: 100%;
  height: 60px;
`

const FilterListItem = styled.div`
  float: left;
  height: 40px;
  width: 100px;
  padding:10px;
  border-right: 1px solid #ff00ff;
`

const FilterBg = styled.div`
  width: 100%;
  height:40px;
  background: #fff;
  margin-top:20px;
`

const FilterItem = styled.div`
  float: left;
  height: 40px;
  width: 100px;
  padding:10px;
  border-right: 1px solid #ff00ff;
`
export default class FilterList extends Component {
  constructor() {
    super()

    this.state = {
      search: ''
    }
  }
  handleAdd = (item) => {
      const value = update(this.props.value, {
          $push: [
            {
            text: item,
            id: Math.random(),
            }
          ]
      })
      this.props.onChange(value)
    }

  handleRemove = (index) => {
      const value = update(this.props.value, {
        $splice: [
          [index, 1]
        ]
      })
      this.props.onChange(value)
    }

  handleFilterUpdate = event => {
    this.setState({ search: event.target.value })
  }

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.search}
          onChange={this.handleFilterUpdate}
          placeholder="Hledat podle nazvu"
        />
        {this.state.search}
        <FilterListBg>
          {
            this.props.filterItems.filter(items => items.text.toLowerCase().indexOf(this.state.search.toLowerCase()) >= 0)
            .map((item,cat,index) =>
              <FilterListItem key={item.id} onClick={()=>this.handleAdd(item.text)}>
                {item.text}
              </FilterListItem>
            )
          }
        </FilterListBg>
        Aktivní filtry
        <FilterBg>
          {
            this.props.value.map((item, index) =>
            <FilterItem key={item.id} onClick={this.handleRemove}>
              {item.text}
            </FilterItem>
            )
          }
        </FilterBg>

      </div>
    )
  }
}

1 个答案:

答案 0 :(得分:0)

假设您想要显示filterList匹配的项目,那么这项工作应该是不是很简单?

const filterTexts = this.state.filter.map(item => item.text);
const itemsToShow = this.state.items.filter(
                      item => filterTexts.indexOf(item.cat) !== -1);

然后您可以映射itemsToShow以创建您的单元格。

如果您想要单行简单地复制粘贴:

this.state.items.filter(items => this.state.filterItems.map(item => item.text)
                          .indexOf(items.cat) !== -1 )
    .map(item =>
        <Cell>
            {console.log(this.state.filter.text)}
            <div>{item.cat}</div>
            <div>{item.text}</div>
        </Cell>
    )