React:使用多个复选框过滤数组列表

Posted

技术标签:

【中文标题】React:使用多个复选框过滤数组列表【英文标题】:React: filter array list using Multiple CheckBoxes 【发布时间】:2022-01-20 15:45:19 【问题描述】:

我正在尝试根据多个条件从 Material UI 自动完成中过滤对象数组列表。然而 onchange 方法只返回第一个状态。我的意思是;

-- 常量数组 = [1, 2, 2, 3, 4, 4]

-- 过滤 2 //return 2, 2

-- 用户更改条件为过滤 2 和 3 // null

//Array for checkbox
const races = [
  'Akita',
  'American Bulldog',
  'Barbet',
  'Beaglier',
  'Cavapoo',
  'Chihuahua',
  'Dachshund',
  'Goldador',
  'Virginia Andrews',
  'Golden Retriever',
];

const class = () => 
//Array for list data 
const [array, setArray] = useState([ // this only change in the first render
   id: 1, title: 'Akita from place1', race: "Akita" ,
   id: 2, title: 'Akita from place2', race: "Akita" ,
   id: 3, title: 'Akita from place3', race: "Akita" ,
   id: 4, title: 'Chihuahua from place4', race: "Chihuahua" ,
   id: 5, title: 'Cockapoo from place5', race: "Cockapoo" ,
   id: 6, title: 'Dachshund from place6', race: "Dachshund" ,
   id: 7, title: 'Dutch Shepherd from place7', race: "Dutch Shepherd" ,
   id: 8, title: "Bulldog from place8", race: "Bulldog" ,
   id: 9, title: 'Goldador from place9', race: "Goldador" ,
])

//Array for filter
const [filteredArray, setFilteredArray]= useState<any | null>(array || null) // use this to print 


//Onchange for material ui autocomplete checkbox
    const handleArrayChanges = (event, value) => 
      if (value)   
        const data = array.filter(data => data.race.includes(value)).map(filteredName => 
          return filteredName
        )
        setFilteredArray(data);
       else 
        const data2 = array.filter(data => data.race.includes(value)).map(filteredName => 
          return !filteredName;  
        )

        setFilteredArray(data2)
      
      console.log(value)
      console.log(data)
   ;

 return (
<Grid container xs=10 sm=10 md=10 lg=12 xl=8 spacing=3 style=marginTop: 50>
 <Autocomplete
              multiple
              id="checkboxes-tags-demo"
              options=races
              disableCloseOnSelect
              onChange=handleArrayChanges
              getOptionLabel=(option) => option
              renderTags=(value, getTagProps) => 
                const numTags = value.length;
                const limitTags = 1;
        
                return (
                  <>
                    value.slice(0, limitTags).map((option, index) => (
                      <Chip
                        ...getTagProps( index )
                        key=index
                        label=option
                      />
                    ))
        
                    numTags > limitTags && ` +$numTags - limitTags`
                  </>
                );
              
              PaperComponent=( children ) => (
                <Paper style= width: 1000 >children</Paper>
              )
              renderOption=(props, option,  selected ) => (
                <li ...props>
                  <Checkbox
                    icon=icon
                    checkedIcon=checkedIcon
                    checked=selected
                  />
                  option

                </li>
              )
              style= width: 300 
              renderInput=(params) => (
                <TextField ...params label="Search for dog breeds"
                style=backgroundColor: "#EEEEEE" variant="outlined" size="medium" 
                />
              )      
            />
    filteredArray?.map((data, _index) => (
        <Grid item xs=3>
        <Card key=_index sx= maxWidth: 300 >
      <CardMedia component="img"  image=image  />
      <CardContent>
        <Typography gutterBottom variant="h5" component="div">
          data.title
        </Typography>
        <Typography variant="body2" color="text.secondary">
          data.race
        </Typography>
      </CardContent>
      <CardActions>
        <Button size="small">Share</Button>
        <Button size="small">Learn More</Button>
      </CardActions>
    </Card>
      </Grid>

 
    ))
</Grid>

我知道 usetate 正在推送当前值,这使得下一个条件不返回任何内容,因为没有数据。但我不知道如何解决这个问题。

https://codesandbox.io/s/infallible-beaver-zdvn7?file=/src/App.js

【问题讨论】:

handleArrayChangesvalue参数的类型是什么?另外,在array.filter(data =&gt; data.race.includes(value)) 中,race 的类型是什么?感觉就像你用数组调用String.prototype.includes(),这很奇怪!我希望我能进一步帮助你,但如果你想让我们解开这样的代码,你真的应该为我们提供一个代码沙箱或类似的东西。 当然,我现在用代码沙箱更新了 【参考方案1】:

编辑:带有工作示例的 Codesandbox:https://codesandbox.io/s/delicate-grass-feqyn

你需要改变你的过滤语句:

尝试替换

 .filter((data) => data.race.includes(value))

.filter((data) => value.includes(data.race))

【讨论】:

嗯,成功了,谢谢。如果你不介意,我还有一个问题。如果我这样做,它会按预期工作,但如果我取消选中复选框,它将不会返回到初始状态。对这种方法有什么想法吗? 是的,我把它放在一个沙箱里。基本上,您需要在组件外部的 const 中设置初始化状态。如果对您有帮助,请将答案标记为正确:)

以上是关于React:使用多个复选框过滤数组列表的主要内容,如果未能解决你的问题,请参考以下文章

通过复选框过滤对象数组

在 React Native 上过滤组件

如何使用同名的多个复选框自定义查询字符串?

Vue JS 基于复选框数组过滤结果

AngularJS ng Repeat - 使用复选框按单个对象属性筛选列表

角阵列变化检测