如何在 React 状态数组中不包含重复值?

Posted

技术标签:

【中文标题】如何在 React 状态数组中不包含重复值?【英文标题】:How do I not include duplicate values in a React state array? 【发布时间】:2019-09-23 16:16:11 【问题描述】:

我想确保我不能将重复值推送到 React 状态的数组中。重复的值仍在数组中。

我尝试过使用.includes,但它不起作用。

const categoryCheck = (category) => 
  let categories = [...this.state.categories]
  if (this.state.categories === undefined) 
    return
  
  console.log(categories, category)
  console.log(!categories.includes(category))
  if (!categories.includes(category) === false) 
    categories.push(category)
    console.log('new category', categories)
   

输入:'cat'

预期结果:['cat'] 实际结果:['cat', 'cat']

更新: 这是我的功能,这就是我的称呼。感谢大家的帮助!

  uniqueCategories = category => 
    //makes sure that there are no duplicate categories in array
    if (category === undefined) 
      return;
    
    let categories = new Set(category);
    categories = Array.from(categories);
    console.log(categories);
    return categories;
  ;

我在另一个函数中这样调用它:

  this.setState(
      categories: this.uniqueCategories([
        ...this.state.categories,
        categoryInput
      ])

【问题讨论】:

您可以使用字典作为***.com/questions/1208222,或者删除重复值作为***.com/questions/9229645 【参考方案1】:
if (!categories.includes(category) === false) 

是双重否定。删除=== false

另一种方法是使用Set 来获得唯一性。通常,集合提供快速查找时间并自动拒绝重复,但对于少量数据,性能可能并不比使用includes 的数组好。

这是一个使用Set的玩具示例:

const useState = React;

const Example = () => 
  const [categories, setCategories] = useState(new Set());
  const [item, setItem] = useState("");
  
  const addCategory = e => 
    if (item.trim()) 
      setCategories(new Set(categories).add(item.trim()));
    
  ;

  return (
    <div>
      <input
        onChange=e => setItem(e.target.value)
        value=item
      />&nbsp;
      <button onClick=addCategory>Add Item</button>
      <ul>[...categories].map(e => <li key=e>e</li>)</ul>
    </div>
  );
;

ReactDOM.render(<Example />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.development.js"></script>

还有一个includes 示例:

const useState = React;

const Example = () => 
  const [categories, setCategories] = useState([]);
  const [item, setItem] = useState("");
  
  const addCategory = e =>  
    const trimmed = item.trim();
    
    if (trimmed && !categories.includes(trimmed)) 
      setCategories(categories.concat(trimmed));
    
  ;

  return (
    <div>
      <input
        onChange=e => setItem(e.target.value)
        value=item
      />&nbsp;
      <button onClick=addCategory>Add Item</button>
      <ul>categories.map(e => <li key=e>e</li>)</ul>
    </div>
  );
;

ReactDOM.render(<Example />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.development.js"></script>

【讨论】:

你有我如何做到这一点的例子吗? 当然,已添加。如果这不能解决问题,请告诉我。【参考方案2】:

你的逻辑颠倒了:

if (!categories.includes(category) === false) ...

如果该项目在数组中不是,将返回true。就用这个吧:

if (!categories.includes(category)) ...

【讨论】:

【参考方案3】:

你可以在 ES6 中使用Set

const categoryCheck = (category) => 
  if (this.state.categories === undefined) 
    return
  
  let categories = new Set(this.state.categories)
  categories.add(category)
  this.setState( categories: Array.from(categories) )

【讨论】:

以上是关于如何在 React 状态数组中不包含重复值?的主要内容,如果未能解决你的问题,请参考以下文章

在reactjs中删除重复项后如何从状态值和setstate创建数组

react js中不相关的组件之间如何共享数据?

React 功能组件 - 当组件返回元素数组时,如何将 refs 传递回父级?

React Native 如何获取已由扩展运算符更新的有状态数组的最后一个值?

如何检查字符串是不是包含子字符串并且在 Bash 中不包含 [重复]

如何在 React Hooks 中向表中添加行而不重复?