【问题标题】:How do I not include duplicate values in a React state array?如何在 React 状态数组中不包含重复值?
【发布时间】: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
      ])

【问题讨论】:

标签: javascript arrays reactjs


【解决方案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) })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 2020-05-15
      相关资源
      最近更新 更多